 if jit then
  jit.off()
  jit.flush()
  print("jit close")
end

real_os_time = real_os_time or os.time 
local Timer   
function os.time(tb) 
    if tb then      
        return real_os_time(tb)    
    end    
    Timer = Timer or require("core.Timer")    
    local t = Timer.now          
    return 0 < t and (t - t % 1000) / 1000 or real_os_time()         
end     
              
real_os_date = real_os_date or os.date                     
local tb = {}     
for i = 1, 64 do                    
    tb[i] = {}                          
end          

                            
local tblen = 0                                 
function os.date(fmt, t)                          
    t = t or os.time()                    
    if fmt == "*t" then                  
        tblen = tblen + 1   
        if #tb < tblen then                  
            tblen = 1                      
        end            
        local d = tb[tblen]       
        d.year, d.month, d.day, d.hour, d.min, d.sec, d.wday,d.yday = global.date(t)        
        return d             
    else
        return real_os_date(fmt, t) 
    end 
end 

adj = adj or {}
envs = envs or {}
file_last_modify_time = file_last_modify_time or {}
loaded = loaded or {}
str2filename = str2filename or {}
local sta = {}
tb_loadfile = tb_loadfile or {} 
local function hot_dfs(a)
    if loaded[a] then
        print("hot=====", a)  
        loaded[a] = nil
        for b in pairs(adj[a]) do 
            hot_dfs(b)  
        end   
    end
end 

local function hot()
    for k, v in pairs(str2filename) do
        local a = global.get_file_last_modify_time(v)   
        if a ~= file_last_modify_time[k] then
            file_last_modify_time[k] = a 
            tb_loadfile[k] = nil    
            hot_dfs(k)
        end
    end 
end
 
collectgarbage("step", 100000)
hot()
collectgarbage("step", 100000)

local path = {
    "script/",
    "script/module/", 
}  

local require_cnt = 0 
_G.old_require =  _G.old_require or require 

threadID = threadID or nil
function _G.get_tid() 
    if not threadID then  
        threadID = _G.get_thread_id(_G.logic_id) 
    end  
    return threadID     
end 
  
ConfigLoadFile = ConfigLoadFile or nil
function require(str, not_need_exist) 
    if not ConfigLoadFile then
        ConfigLoadFile = {}
        ConfigLoadFile = require("Config") 
        print("load excel project:", ConfigLoadFile.PROJECT_NAME)
    end
    require_cnt = require_cnt + 1 
    adj[str] = adj[str] or {} 
    if sta[#sta] then   
        adj[str][sta[#sta]] = true 
    end 
    sta[#sta + 1] = str    
    if not loaded[str] then  
        loaded[str] = true  
        envs[str] = envs[str] or {  
            _G = _G,  
            assert = assert, 
            error = error, 
            getfenv = getfenv,  
            ipairs = ipairs,  
            load = load,   
            next = next,   
            pairs = pairs,
            pcall = pcall,   
            print = print,  
            require = require,    
            setmetatable = setmetatable,
            tonumber = tonumber,  
            tostring = tostring, 
            type = type,  

            debug = debug,  
            io = io,  
            math = math, 
            string = string,   
            table = table,  
            os = os, 
        } 
        envs[str]._ENV = envs[str]   
        if not str2filename[str] then    
            local filename = string.gsub(str, "%.", "/") .. ".lua"  
            local _, excelPos = string.find(filename, "excel/", 1, true)
            if excelPos then
                local prename = string.sub(filename, 1, excelPos)
                local lastname = string.sub(filename, excelPos+1, #filename) 
                filename = prename .. ConfigLoadFile.PROJECT_NAME .. "/" .. lastname
            end              
            local ac  
            for _, v in ipairs(path) do  
                local pre_filename = v .. filename    
                local a = global.get_file_last_modify_time(pre_filename)   
                if a ~= 0 then 
                    str2filename[str] = pre_filename   
                    file_last_modify_time[str] = a     
                    ac = true  
                    break  
                end
            end             
            if not ac then  
                if not_need_exist then
                    return
                else
                    assert(nil, str .. " not exist") 
                end   
            end 
        end 
        local fun = tb_loadfile[str] 
        if not fun then   
            local err  
            fun, err = loadfile(str2filename[str], nil, envs[str])  

            if not fun then 
                assert(nil, err) 
            end  
        end    
        local require_cnt_old = require_cnt   
        fun()    
        if require_cnt_old < require_cnt then   
            tb_loadfile[str] = fun    
        end   
    end  
    sta[#sta] = nil   
    return envs[str]  
end   
modtb = modtb or nil
local function cmd2str(cmd)
    if modtb then  
      return
    end  
    local f = io.popen(cmd) 
    local str = f:read("*a")   
    assert(io.close(f)) 
    return str 
end 
 
local function get_modules(str)
    if modtb then
        return modtb   
    end  
    modtb = {}
    local i = 1  
    while true do 
        local j = string.find(str, "\n", i)  
        if not j then  
            break
        end 
        modtb[#modtb + 1] = string.sub(str, i, j - 1) 
        i = j + 1
    end 
    table.sort(modtb)
    return modtb   
end
 
local cmd = os.getenv("OS") == "Windows_NT" and "dir/b script\\module" or "ls script/module"
local m = get_modules(cmd2str(cmd))
local Msg = require("core.Msg") 
local InnerMsg = require("core.InnerMsg")
local Config = require("Config")  

if Config.IS_MIDDLE == true then
    _G['is_middle'] = true
end

function init_proto_id()  
    if has_init_proto_id then 
        return  
    end  
    local protoIDS = require("common.ProtoID")  
    has_init_proto_id = true  
    Msg.proto_id = {}      
 
    for k,v in pairs(protoIDS) do 
        if type(k) == "number" then 
            Msg.proto_id[v] = k 
        end
    end

    protoIDS = require("common.InnerProtoID")
    InnerMsg.proto_id = {}   
    for k,v in pairs(protoIDS) do
        if type(k) == "number" then  
            InnerMsg.proto_id[v] = k    
        end
    end 
end 
init_proto_id() 
require("core.PKLimit")

local function requireModule(module_name) 
    local proto = require(module_name .. ".Proto", true)
    if not proto then
        return
    end
    local handler = require(module_name .. ".Handler", true)
    for k, v in pairs(proto) do
        local sub = string.sub(k, 1, 2)
        if sub == "CG" or sub == "GC" then
            if sub == "CG" and not handler[k] then
                assert(nil, k .. " not exist in HandlerL.lua")
            end
            local pid = Msg.proto_id[k]
            Msg.register(k, pid, v, handler and handler[k])
        elseif sub == "WL" or sub == "LW" then
            assert(nil, k.." can't define here")            
        end
    end 
end
for _, v in pairs(m) do
    requireModule(v)
end
 
local function initInnerProto()
    local proto = require("common.InnerProto")
    if not proto then
        return 
    end
    local handler = require("common.InnerHandler", true)
    for k, v in pairs(proto) do
        local sub = string.sub(k, 1, 2)
        local pid = InnerMsg.proto_id[k]
        if sub == "LW" or sub == "WL" then
            if sub == "LW" and not handler[k] then
                assert(nil, k .. " not exist in handler.lua")
            end     
            InnerMsg.register(k, pid, v, handler and handler[k])     
        elseif sub == "CG" or sub == "GC" then
            assert(nil, k.." can't define here")
        end        
    end
end 
initInnerProto() 
    
local Log = require("common.Log") 
local Timer = require("core.Timer")
local Monitor = require("core.Monitor") 
local AdminLogic = require("AdminLogic") 
local ObjHuman = require("core.ObjHuman")   
local Obj = require("core.Obj")
local msg_ex = _G.msg_ex 
function handlerMsg(fd, protoId) 
    local container = Msg.cg[protoId] 
    if msg_ex.read(protoId, container) then 
        print("err handlerMsg msg_ex.read", protoId, Msg.proto_name[protoId])
        local mm = Msg.gc.GC_DISCONNECT  
        mm.code = 0
        mm.msg = "proto err" 
        Msg.send(mm, fd)    
        return
    end  
    local id = ObjHuman.fds[fd]
    if id then
        local human = Obj.objs[id] 
        if not human then 
            assert() 
        end 
        if protoId == Msg.proto_id.CG_ASK_LOGIN then 
            assert()    
        end
        Monitor.handlePacket(human, container, protoId)  
    else        
        if protoId ~= Msg.proto_id.CG_AA_DISCONNECT and 
            protoId ~= Msg.proto_id.CG_ASK_LOGIN and
            protoId ~= Msg.proto_id.CG_MIDDLE_LOGIN and 
            protoId ~= Msg.proto_id.CG_TEST_PROTO then
            --如果登录了两个相同的帐号，第二个帐号把第一个帐号踢掉后，第一个帐号在收到断开的消息之前，可能继续发包，就会跑到这里来 
            return
        end
        Monitor.handlePacket(fd, container, protoId)
    end    
end 
 
Timer.now = global.get_msec() --当前时间 
function handlerTime(msec)    
    Timer.handlerTime(msec) 
end  

function handlerAdmin(fd, input)
    return AdminLogic.handleAdminRequest(fd, input)
end   

function handlerInner(fd) -- 处理跨服和普通服之间的消息
    local ret, proto_id = _G.msg_inner_parse.readint() 
    assert(ret)

    local container = nil
    if Config.IS_MIDDLE then        -- logic传来
        container = InnerMsg.lw[proto_id]        
    else                            -- world传来
        container = InnerMsg.wl[proto_id]
    end

    InnerMsg.readMsg(proto_id, container)
    Monitor.handleInnerPacket(fd, container, proto_id)
end    
-- 启动之后需要做的事情，没有直接写在某个模块的init里面的原因是因为这些init需要启动初始化完完整数据之后才能进行      
local function initAfterStart() 
    if has_init then return end         
    has_init = true    
    math.randomseed(os.time()) 
    require("core.RoleDel").roleDel()       
    require("common.Check").check()
    require("common.CommonDB").init()        
	require("role.RoleDBLogic").roleDBInit()
	require("drill.DrillDB").initAfterStart() 
    require("jjc.JjcDB").initAfterStart()    
    require("billboard.BillboardDB").initAfterStart() 
    require("middle.MiddleActGroup").initAfterStart()
    require("theStars.TheStarsDBLogic").init()
    require("copy.CopyManage").init()
    require("combat.CombatObj").initAfterStart()
    require("bag.DropSpecial").initAfterStart()
    require("warReport.WarReportLogic").initAfterStart()
    require("battle.BattleLogic").initAfterStart()
    require("jjcGodWar.JjcGodWarDB").initAfterStart()
    require("union.UnionWarDBLogic").init()
    require("middle.MiddleConnect").initAfterStart()
    require("role.RoleStrongLogic").initAfterStart() 
    require("huanjingTower.HuanjingTowerLogic").initSeverTower()  
    require("yjTreasure.YjTreasureDB").changeOldToNewDB()
    require("yjTreasure.YjTreasureDB").initAfterStart()  
    require("union.UnionWarDBLogic").init()
    require("zhanbu.ZhanbuLogic").initAfterStart() 
    require("absAct.HeroGrowUp").initAfterStart()
    require("present.OpenServerRankDB").initAfterStart()
    require("absAct.AbsActBillboardMiddleLogic").initAfterStart()
    require("mozhu.MoZhuDB").initAfterStart()
    require("common.CommonRankDB").initAfterStart()
    math.randomseed(os.time())
end 


local function initAfterHot()
	require("platform.ProjectLogic").initAfterHot()
	require("hero.HeroDefine").initAfterHot() 
	require("common.CommonDB").init()
	require("roleSystem.RoleSystemLogic").initAfterHot() 
	require("drawCard.DrawCardLogic").initAfterHot()
	require("absAct.AbsActLogic").initAfterHot() 
    require("yunying.YunYingLogic").init() 
    require("fuwen.FuwenGrid").initAfterHot() 
    require("skin.SkinLogic").initAfterHot() 
    require("jjc.JjcActLogic").init() 
    require("combat.CombatLogic").init() 
    require("combat.Skill").initAfterHot()  
	require("present.WelfareGiftLogic").initAfterHot()
    require("combat.JibanLogic").initAfterHot()
    require("guide.GuideLogic").initAfterHot()
    require("chengjiu.ChengjiuLogic").initAfterHot()
    require("huanjingTower.HuanjingTowerLogic").initSeverTower()
    require("core.RoleDel").initAfterHot()
    require("platform.FanliLogic").initAfterHot() 
    require("moshou.MoshouLogic").initAfterHot()		
    require("chengjiu.ChengjiuLogic").initAfterHotTemp()
    require("present.OpenAct").initAfterHot()
    require("absAct.PremiumGiftLogic").initAfterHot()
    require("absAct.HeroGrowUp").initAfterHot()
    require("absAct.WishGiftLogic").initAfterHot()
    require("present.CDK").initAfterHot()
    require("topup.BuyLogic").initAfterHot()
    Log.write(Log.LOGID_TEST, "hot success")
end  
initAfterStart()
initAfterHot() 


collectgarbage("collect")
print("logic:"..collectgarbage("count"))--, jit.status()) 