BONUS_D = {}
setmetatable(BONUS_D, {__index = _G})
local _ENV = BONUS_D
local bonus_times_list={}
local bonus_times_limit_list = {}
local MAX_INTERVAL = 600
local function attrib_bonus(attribs, bonus_type)
local attrib_list = {}
local money = {}
for _, info in pairs(attribs) do
local attrib = {}
local ctr_ob
local ob = remove_get(info, "ob")
if ob and ob:get_owner() then
ctr_ob = ob:get_owner()
end
ctr_ob = ctr_ob or ob
trace("ob type is %o", ctr_ob:query("ob_type"))
if ctr_ob and ctr_ob:query("ob_type") == OB_TYPE_USER then
local ctr_rid = ctr_ob:get_rid()
local ob_rid = ob:get_rid()
for field, value in pairs(info) do
local ori_value = ob:query(field) or 0
local cfg_value = value
if field == "money" then
end
if ATTRIB_D.add_attrib(ob, field, cfg_value) then
value = math.min(ob:query(field) - ori_value, cfg_value)
if field == "money" then
money[ctr_rid] = money[ctr_rid] or 0
money[ctr_rid] = money[ctr_rid] + value
elseif field == "exp"then
trace("ob is %o ob+type = %o", ob, ob:query("ob_type"))
if ob:query("ob_type") == OB_TYPE_USER then
USER_D.try_level_up(ob)
elseif ob:query("ob_type") == OB_TYPE_HERO then
HERO_D.try_level_up(ob)
end
attrib["exp"] = value
else
attrib[field] = value
end
end
end
attrib_list[ctr_rid] = attrib_list[ctr_rid] or {}
attrib_list[ctr_rid][ob_rid] = attrib_list[ctr_rid][ob_rid] or {}
for field, value in pairs(attrib) do
attrib_list[ctr_rid][ob_rid][field] = attrib_list[ctr_rid][ob_rid][field] or 0
attrib_list[ctr_rid][ob_rid][field] = attrib_list[ctr_rid][ob_rid][field] + value
end
else
trace("ERROR: container ob is not a user in BONUS_D.attrib_bonus\n")
end
end
local attrib_list_temp ={}
for ctr_rid, info in pairs(attrib_list) do
local attrib_array = {}
for ob_rid, attrib_info in pairs(info) do
attrib_info["rid"] = ob_rid
attrib_array[#attrib_array + 1] = attrib_info
end
attrib_list_temp[ctr_rid] = attrib_array
end
return attrib_list_temp
end
function cal_property(property, class_id, amount, ob)
if not property then
property = {}
end
local max_amount = CALC_ITEM_MAX_AMOUNT(class_id)
local integer = math.floor(amount/max_amount)
local remainder = amount % max_amount
for i=1, integer do
property[#property+1] =
{
ob = ob,
class_id = class_id,
amount = max_amount,
}
end
if remainder > 0 then
property[#property+1] =
{
ob = ob,
class_id = class_id,
amount = remainder,
}
end
return property
end
local function property_bonus(propertys, bonus_type)
local list ={}
for _, info in pairs(propertys) do
local extra = remove_get(info, "extra") or {}
local ob = remove_get(info, "ob")
if ob and ob:query("ob_type") == OB_TYPE_USER then
local ob_rid = ob:get_rid()
list[ob_rid] = list[ob_rid] or {}
local success, gain_list = ob:get_container():recieve_property(info)
if success then
for _,v in pairs(gain_list) do
table.insert(list[ob_rid], v)
end
end
else
trace("ERROR: ob is not a user_type in BUNOS_D.property_bonus\n")
end
end
return list
end
local function caculate_bonus_property_times(property_info)
do return end
local temp_list ={}
for _, info in pairs(property_info) do
if is_object(info["ob"]) and info["ob"]:query("ob_type") == OB_TYPE_USER then
temp_list[info["ob"]:query("rid")] = true
end
end
for rid,_ in pairs(temp_list) do
bonus_times_list[rid] = bonus_times_list[rid] or {}
bonus_times_list[rid].property = bonus_times_list[rid].property or 0
bonus_times_list[rid].property = bonus_times_list[rid].property + 1
end
end
local function caculate_bonus_attrib_times(attrib_info)
do return end
local temp_list ={money={}, exp={}}
local owner_rid
for _, info in pairs(attrib_info) do
if is_object(info["ob"]) then
if info["ob"]:query("ob_type") == OB_TYPE_USER then
owner_rid = info["ob"]:query("rid")
else
owner_rid = info["ob"]:query("owner")
end
if owner_rid then
if info["money"] then
temp_list.money[owner_rid] = true
elseif info["exp"] then
temp_list.exp[owner_rid] = true
end
end
end
end
for rid,_ in pairs(temp_list.money) do
bonus_times_list[rid] = bonus_times_list[rid] or {}
bonus_times_list[rid].money = bonus_times_list[rid].money or 0
bonus_times_list[rid].money = bonus_times_list[rid].money + 1
end
for rid,_ in pairs(temp_list.exp) do
bonus_times_list[rid] = bonus_times_list[rid] or {}
bonus_times_list[rid].exp = bonus_times_list[rid].exp or 0
bonus_times_list[rid].exp = bonus_times_list[rid].exp + 1
end
end
function write_log(rid, online_time)
local info = ""
if bonus_times_list[rid] then
info = table.tostring(bonus_times_list[rid])
bonus_times_list[rid] = nil
end
LOG_D.to_log(LOG_TYPE_BONUS_TIMES, rid, tostring(online_time) , "", info)
end
function calc_bonus(script, ...)
if is_int(script) then
if script > 0 then
return (INVOKE_SCRIPT(script, ...))
end
else
return (INVOKE_SCRIPT_ALIAS(script, ...))
end
end
function calc_property_bonus(cob, attacker_list, defenser_list)
property_list = {}
for _,defenser in pairs(defenser_list) do
local script = defenser:query("property_bonus_script")
if script and script > 1 then
local property = calc_bonus(script, cob, defenser,
attacker_list, defenser_list)
tinsertvalues(property_list, property)
end
end
return property_list
end
function pre_deal_bonus(bonus_info)
bonus_info.attrib = bonus_info.attrib or {}
local new_property = {}
for _,v in ipairs(bonus_info.property or {}) do
if v.class_id == GET_GOLD_ID() then
table.insert(bonus_info.attrib, {gold = v.amount, ob = v.ob})
elseif v.class_id == GET_STONE_ID() then
table.insert(bonus_info.attrib, {stone = v.amount, ob = v.ob})
else
table.insert(new_property, v)
end
end
bonus_info.property = new_property
end
function do_user_bonus(user, bonus_info, bonus_type, show_type)
pre_deal_bonus(bonus_info)
for _,v in ipairs(bonus_info.attrib) do
if not v.ob then
v.ob = user
end
end
for _,v in ipairs(bonus_info.property) do
if not v.ob then
v.ob = user
end
end
return do_bonus(bonus_info, bonus_type, show_type)
end
function do_bonus(bonus_info, bonus_type, show_type)
if not is_mapping(bonus_info) then
return
end
if not show_type then
show_type = BONUS_TYPE_SHOW
end
local attrib_list = {}
local property_list = {}
local attribs = bonus_info["attrib"]
if is_array(attribs) then
attrib_list = attrib_bonus(attribs, bonus_type)
end
local propertys = bonus_info["property"]
if is_array(propertys) then
property_list = property_bonus(propertys, bonus_type)
end
for rid, attrib in pairs(attrib_list) do
local bonus = {}
if sizeof(attrib) > 0 then
bonus["attribs"] = attrib
end
if sizeof(bonus) > 0 then
local ob = find_object_by_rid(rid)
if is_object(ob) then
ob:send_message(MSG_BONUS, bonus, show_type)
caculate_bonus_times_limit(ob, bonus_type)
end
end
end
for rid, property in pairs(property_list) do
if sizeof(property) > 0 then
local bonus = {properties = property}
local ob = find_object_by_rid(rid)
if is_object(ob) then
ob:send_message(MSG_BONUS, bonus, show_type)
caculate_bonus_times_limit(ob, bonus_type)
end
end
end
return true, property_list, attrib_list
end
function caculate_bonus_times_limit(user, bonus_type)
do return end
local times = bonus_times_limit_list[bonus_type] or 250
local user_bonus_times = user:query_temp("user_bonus_times") or {}
local queue = user_bonus_times[bonus_type] or Queue.new()
local cur_time = os.time()
while Queue.getFirst(queue) and cur_time - Queue.getFirst(queue) > MAX_INTERVAL do
Queue.popFirst(queue)
end
Queue.pushBack(queue, cur_time)
if Queue.getSize(queue) >= times then
INTERNAL_COMM_D.send_message(AAA_ID, CMD_GS_FREEZE_ACCOUNT, user:query("account"))
local queue_string = save_string(queue)
INTERNAL_COMM_D.send_message(SPA_ID, CMD_GS_BONUS_EXCEPTION, user:query("account"),
user:query("rid"), bonus_type, queue_string)
USER_D.user_logout(user)
return
end
user_bonus_times[bonus_type] = queue
user:set_temp("user_bonus_times", user_bonus_times)
end
function get_bonus_times_list()
return bonus_times_list
end
function get_limit_list()
return bonus_times_limit_list
end
function create()
end
create()