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
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package ReloadModule
#
# @todo:ÖØ¶Á½Å±¾Ä£¿é
# @author hxp
# @date 2016-8-5
# @version 1.0
#
# ÏêϸÃèÊö: ÖضÁ½Å±¾Ä£¿é£¬½ö¶Ô±ä¸üµÄ½Å±¾ÖضÁ£¬ÓÅ»¯ÈȲ¿Êð
#
#-------------------------------------------------------------------------------
#"""Version = 2016-8-5 19:00"""
#-------------------------------------------------------------------------------
 
import ReadChConfig
import ShareDefine
import GameWorld
import ChConfig
 
import sys
import os
 
g_moduleFileCMTimeDict = {} # Ä£¿éÎļþ´´½¨¼°ÐÞ¸Äʱ¼ä
 
## Ë¢Ð½ű¾Ä£¿é´´½¨¼°ÐÞ¸Äʱ¼ä
def RefreshModuleFileCMTime(isServerInitOK):
    global g_moduleFileCMTimeDict
    
    isOpenChagneReload, GameServerReloadVersion, MapServerReloadVersion  = ReadChConfig.GetEvalChConfig("PyReloadVersion")
    if not isOpenChagneReload:
        return
 
    g_moduleFileCMTimeDict = {}
    GameWorld.Log("ˢнű¾Îļþʱ¼ä isServerInitOK=%s" % isServerInitOK)
    for parent, dirnames, filenames in os.walk(ChConfig.ScriptPath):
        #DebugLog("parent=%s, dirnames=%s" % (parent, dirnames))
        for filename in filenames:
            if "py" not in filename:
                continue
            fullPath = os.path.join(parent, filename)
            ctime = os.path.getctime(fullPath) # »ñÈ¡ÎļþµÄ´´½¨Ê±¼ä
            mtime = os.path.getmtime(fullPath) # »ñÈ¡ÎļþµÄÐÞ¸Äʱ¼ä 
            #DebugLog("    filename=%s, fullPath=%s" % (filename, fullPath))
            g_moduleFileCMTimeDict[filename] = [ctime, mtime]
    GameWorld.Log("    ½Å±¾×ÜÊý: %s" % len(g_moduleFileCMTimeDict))
    
    if isServerInitOK:
        GameWorld.GetGameWorld().SetDict(ShareDefine.Def_Notify_WorldKey_GameServerScriptReloadVersion, GameServerReloadVersion)
        GameWorld.GetGameWorld().SetDict(ShareDefine.Def_Notify_WorldKey_MapServerScriptReloadVersion, MapServerReloadVersion)
        GameWorld.Log("    GameServerReloadVersion=%s,MapServerReloadVersion=%s" % (GameServerReloadVersion, MapServerReloadVersion))
    
    return
 
## Ä£¿é½Å±¾Èȸü
## ´Ë¹¦Äܲ»Í¨¹ý½Å±¾ÖضÁ´¥·¢£¬ÓÉÓڽű¾ÖضÁÔÚC++ÖÐÒÑĬÈÏÖØ¶ÁËùÓнű¾Îļþ, ½öÔÚÖØ¶ÁÅäÖÃÖд¥·¢¼ì²é
def DoModuleHotUpdate():
    isOpenChagneReload, GameServerReloadVersion, MapServerReloadVersion  = ReadChConfig.GetEvalChConfig("PyReloadVersion")
    if not isOpenChagneReload:
        return
    
    __DoGameServerScriptReload(GameServerReloadVersion)
    __Broadcast_MapServerScriptReload(MapServerReloadVersion)
    return
 
## ¹ã²¥¸÷µØÍ¼£¬Í¨Öª½øÐнű¾¸üÐÂ
def __Broadcast_MapServerScriptReload(MapServerReloadVersion):
    curMSVersion = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_MapServerScriptReloadVersion)
    
    if curMSVersion == MapServerReloadVersion:
        GameWorld.Log("MapServer½Å±¾°æ±¾Ïàͬ²»ÖضÁ, curMSVersion=%s" % curMSVersion)
        return
    
    # Í¨ÖªµØÍ¼½Å±¾ÖضÁ
    GameWorld.GetGameWorld().SetDict(ShareDefine.Def_Notify_WorldKey_MapServerScriptReloadVersion, MapServerReloadVersion)
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_MapServerScriptReloadVersion, MapServerReloadVersion)
    GameWorld.Log("֪ͨMapServer½Å±¾ÖضÁ, mapServerVersion=%s" % MapServerReloadVersion)
    return
 
 
def __DoGameServerScriptReload(GameServerReloadVersion):
    global g_moduleFileCMTimeDict
    
    # ÕâÀï»á±ä¿ÕÒ»°ãÊÇÒòΪdebugÆÚ¼äʹÓÃÁËÖØ¶ÁËùÓнű¾µ¼Ö£¬Ò»°ãÕýʽ»·¾³²»ÔÙʹÓÃ֮ǰµÄÖØ¶Á½Å±¾£¬ËùÒÔ²»»áÓпյÄÇé¿ö
    if not g_moduleFileCMTimeDict:
        RefreshModuleFileCMTime(False)
        return
    
    curGSVersion = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_GameServerScriptReloadVersion)
    
    if curGSVersion == GameServerReloadVersion:
        GameWorld.Log("GameServer½Å±¾°æ±¾Ïàͬ²»ÖضÁ, curGSVersion=%s" % curGSVersion)
        return
    
    GameWorld.Log("GameServer¿ªÊ¼½Å±¾ÖضÁ GameServerReloadVersion=%s" % GameServerReloadVersion)
    moduleNameDict = {}
    GameWorld.GetGameWorld().SetDict(ShareDefine.Def_Notify_WorldKey_GameServerScriptReloadVersion, GameServerReloadVersion)
    
    for moduleKey, module in sys.modules.items():
        if "py" not in str(module):
            #GameWorld.DebugLog("    not py module: %s=%s" % (moduleKey, module))
            continue
        
        moduleName = moduleKey.split(".")[-1]
        moduleList = moduleNameDict.get(moduleName, [])
        moduleList.append(moduleKey) # ÓÐЩģ¿é»á²úÉú¶à¸ö...£¿
        moduleNameDict[moduleName] = moduleList
            
    for parent, dirnames, filenames in os.walk(ChConfig.ScriptPath):
        #DebugLog("parent=%s, dirnames=%s" % (parent, dirnames))
        for filename in filenames:
            if "py" not in filename:
                continue
            
            curModuleName = filename.split('.')[0]
            if curModuleName == __name__:
                #GameWorld.DebugLog("    ±¾½Å±¾²»¸üÐÂ: %s" % curModuleName)
                continue
 
            fullPath = os.path.join(parent, filename)
            curCTime = os.path.getctime(fullPath) # »ñÈ¡ÎļþµÄ´´½¨Ê±¼ä
            curMTime = os.path.getmtime(fullPath) # »ñÈ¡ÎļþµÄÐÞ¸Äʱ¼ä
            if filename in g_moduleFileCMTimeDict:
                ctime, mtime = g_moduleFileCMTimeDict[filename]
                # Ê±¼äÏàͬ´ú±í½Å±¾Ã»±ä£¬²»½øÐÐÖØ¶Á
                if ctime == curCTime and mtime == curMTime:
                    #GameWorld.DebugLog("    not change %s : %s" % (filename, fullPath))
                    continue
            g_moduleFileCMTimeDict[filename] = curCTime, curMTime
            
            if curModuleName in moduleNameDict:
                for moduleKey in moduleNameDict[curModuleName]:
                    __DoModuleReload(moduleKey)
                
    GameWorld.Log("    GameServer½Å±¾ÖضÁ OK!")   
    return
 
def __DoModuleReload(moduleKey):
    module = sys.modules.get(moduleKey)
    if not module:
        return
    try:
        # ÕâÀïÏȽøÐмòµ¥µÄÖ±½ÓÖØ¶Á£¬ÈçÓÐÐèÒª£¬¿ÉÓÅ»¯ÖضÁÂß¼­£¬ÊµÏÖ²»Í¬µÄÖØ¶ÁÐèÇó£¬Èç±£ÁôÈ«¾Ö±äÁ¿ÖµµÈ
        # Ä¿Ç°Ö±½ÓÖØ¶ÁÒѾ­¿ÉÒÔÓ¦¶Ô´ó²¿·ÖÐèÇ󣬹ÊÔݲ»×öÖ§³Ö
        reload(module)
        GameWorld.Log("    reload module %s, %s" % (moduleKey, module))
    except Exception:
        GameWorld.ErrLog("    reload module err! %s, %s" % (moduleKey, module))
    return