tdengine 0.1.2

game server for Rust
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
-- bonusd.lua
-- Created by wugd
-- 负责奖励相关的功能模块

-- 声明模块名
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 = {}

    --分别对attribs里的对象执行奖励操作
    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"))
        --不存在属主,或者ob不是玩家,则不操作
        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
                    -- 如果有多倍金钱活动,则乘上倍率
--                  cfg_value = value*ACTIVITY_MULTIPLE_MONEY.get_money_multiple()
                end

                --如果操作成功,记录日志,以及要发送给客户端的信息
                if ATTRIB_D.add_attrib(ob, field, cfg_value) then
                    -- value为实际增加的值
                    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
                        --LOG_D.to_log(LOG_TYPE_EXP, ob_rid, tostring(value), "", "")
                    else
                        attrib[field] = value
                    end
                end
            end
              --初始化map
            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 ={}

    --整理attrib_list,将ctr_rid对应的值改为数组;
    --将ob_rid,存入对应的值中;
    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

-- 组合bonus_info中的property信息(只针对道具,考虑到可叠加问题)
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

--执行奖励操作
--attrib和property均为数组
 --[=[bonus_info = {attrib   =  { { ob  = 奖励对象1,
                                    exp = 33
                                    stone = 10
                                  },
                                  { ob = 奖励对象2,
                                    stone=15,
                                  },
                                  ...
                                }

                    property  = { { ob = 奖励对象,
                                    class_id = 10001,
                                    amount =19,
                                    extra = {   -- 可选参数,宠物才有,传入获得信息
                                                obtain_way = ...,
                                                obtain_record = ...
                                                },
                                            }
                                    ....
                                  } ,

                                  ....
                                }
                    }   --]=]

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
        --caculate_bonus_attrib_times(attribs)
        attrib_list = attrib_bonus(attribs, bonus_type)
    end

    local propertys = bonus_info["property"]

    --如果有物品则进行物品奖励
    if is_array(propertys) then
        --caculate_bonus_property_times(propertys)
        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

    --处理property_list中剩下的奖励
    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
        -- user:notify_dialog_ok($$[218],1)

        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)
        --set_timer(5000,USER_D.user_logout, user)
        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()