]>
Commit | Line | Data |
---|---|---|
1 | /* Copyright (C) Chris Porter 2005 */ | |
2 | /* ALL RIGHTS RESERVED. */ | |
3 | /* Don't put this into the SVN repo. */ | |
4 | /* Copyright (C) Chris Porter 2005 */ | |
5 | ||
6 | #include "../control/control.h" | |
7 | #include "../nick/nick.h" | |
8 | ||
9 | #include "lua.h" | |
10 | ||
11 | int lua_inslua(void *sender, int cargc, char **cargv); | |
12 | int lua_rmlua(void *sender, int cargc, char **cargv); | |
13 | int lua_reloadlua(void *sender, int cargc, char **cargv); | |
14 | int lua_lslua(void *sender, int cargc, char **cargv); | |
15 | int lua_forcegc(void *sender, int cargc, char **cargv); | |
16 | void lua_controlstatus(int hooknum, void *arg); | |
17 | ||
18 | void lua_startcontrol(void) { | |
19 | registercontrolhelpcmd("inslua", NO_DEVELOPER, 1, &lua_inslua, "Usage: inslua <script>\nLoads the supplied Lua script.."); | |
20 | registercontrolhelpcmd("rmlua", NO_DEVELOPER, 1, &lua_rmlua, "Usage: rmlua <script>\nUnloads the supplied Lua script."); | |
21 | registercontrolhelpcmd("reloadlua", NO_DEVELOPER, 1, &lua_reloadlua, "Usage: reloadlua <script>\nReloads the supplied Lua script."); | |
22 | registercontrolhelpcmd("lslua", NO_DEVELOPER, 0, &lua_lslua, "Usage: lslua\nLists all currently loaded Lua scripts and shows their memory usage."); | |
23 | registercontrolhelpcmd("forcegc", NO_DEVELOPER, 1, &lua_forcegc, "Usage: forcegc ?script?\nForces a full garbage collection for a specific script (if supplied), all scripts otherwise."); | |
24 | registerhook(HOOK_CORE_STATSREQUEST, lua_controlstatus); | |
25 | } | |
26 | ||
27 | void lua_destroycontrol(void) { | |
28 | deregistercontrolcmd("inslua", &lua_inslua); | |
29 | deregistercontrolcmd("rmlua", &lua_rmlua); | |
30 | deregistercontrolcmd("reloadlua", &lua_reloadlua); | |
31 | deregistercontrolcmd("lslua", &lua_lslua); | |
32 | deregistercontrolcmd("forcegc", &lua_forcegc); | |
33 | deregisterhook(HOOK_CORE_STATSREQUEST, lua_controlstatus); | |
34 | } | |
35 | ||
36 | int lua_inslua(void *sender, int cargc, char **cargv) { | |
37 | nick *np = (nick *)sender; | |
38 | char *script = cargv[0]; | |
39 | ||
40 | if(cargc < 1) { | |
41 | controlreply(np, "Usage: inslua <script>"); | |
42 | return CMD_ERROR; | |
43 | } | |
44 | ||
45 | if(lua_scriptloaded(script)) { | |
46 | controlreply(np, "Script %s already loaded, or name not valid.", script); | |
47 | return CMD_ERROR; | |
48 | } | |
49 | ||
50 | if(lua_loadscript(script)) { | |
51 | controlreply(np, "Script %s loaded.", script); | |
52 | return CMD_OK; | |
53 | } else { | |
54 | controlreply(np, "Unable to load script %s.", script); | |
55 | return CMD_ERROR; | |
56 | } | |
57 | } | |
58 | ||
59 | int lua_rmlua(void *sender, int cargc, char **cargv) { | |
60 | nick *np = (nick *)sender; | |
61 | char *script = cargv[0]; | |
62 | lua_list *l; | |
63 | ||
64 | if(cargc < 1) { | |
65 | controlreply(np, "Usage: rmmod <script>"); | |
66 | return CMD_ERROR; | |
67 | } | |
68 | ||
69 | l = lua_scriptloaded(script); | |
70 | if(!l) { | |
71 | controlreply(np, "Script %s is not loaded.", script); | |
72 | return CMD_ERROR; | |
73 | } | |
74 | ||
75 | lua_unloadscript(l); | |
76 | controlreply(np, "Script %s unloaded.", script); | |
77 | ||
78 | return CMD_OK; | |
79 | } | |
80 | ||
81 | int lua_reloadlua(void *sender, int cargc, char **cargv) { | |
82 | if(cargc < 1) { | |
83 | controlreply((nick *)sender, "Usage: reloadlua <script>"); | |
84 | return CMD_ERROR; | |
85 | } | |
86 | ||
87 | lua_rmlua(sender, cargc, cargv); | |
88 | ||
89 | return lua_inslua(sender, cargc, cargv); | |
90 | } | |
91 | ||
92 | int lua_lslua(void *sender, int cargc, char **cargv) { | |
93 | nick *np = (nick *)sender; | |
94 | lua_list *l; | |
95 | ||
96 | controlreply(np, "Loaded scripts:"); | |
97 | ||
98 | for(l=lua_head;l;l=l->next) | |
99 | controlreply(np, "%s (mem: %dKb calls: %lu user: %0.2fs sys: %0.2fs)", l->name->content, lua_gc(l->l, LUA_GCCOUNT, 0), l->calls, (double)((double)l->ru_utime.tv_sec + (double)l->ru_utime.tv_usec / USEC_DIFFERENTIAL), (double)((double)l->ru_stime.tv_sec + (double)l->ru_stime.tv_usec / USEC_DIFFERENTIAL)); | |
100 | ||
101 | controlreply(np, "Done."); | |
102 | ||
103 | return CMD_OK; | |
104 | } | |
105 | ||
106 | void lua_controlstatus(int hooknum, void *arg) { | |
107 | char buf[1024]; | |
108 | int memusage = 0; | |
109 | lua_list *l; | |
110 | ||
111 | if ((long)arg <= 10) | |
112 | return; | |
113 | ||
114 | for(l=lua_head;l;l=l->next) | |
115 | memusage+=lua_gc(l->l, LUA_GCCOUNT, 0); | |
116 | ||
117 | snprintf(buf, sizeof(buf), "Lua : %dKb in use in total by scripts.", memusage); | |
118 | triggerhook(HOOK_CORE_STATSREPLY, buf); | |
119 | } | |
120 | ||
121 | int lua_forcegc(void *sender, int cargc, char **cargv) { | |
122 | nick *np = (nick *)sender; | |
123 | lua_list *l; | |
124 | int membefore = 0, memafter = 0; | |
125 | if(cargc == 0) { | |
126 | for(l=lua_head;l;l=l->next) { | |
127 | membefore+=lua_gc(l->l, LUA_GCCOUNT, 0); | |
128 | controlreply(np, "GC'ing %s. . .", l->name->content); | |
129 | lua_gc(l->l, LUA_GCCOLLECT, 0); | |
130 | memafter+=lua_gc(l->l, LUA_GCCOUNT, 0); | |
131 | } | |
132 | } else { | |
133 | l = lua_scriptloaded(cargv[0]); | |
134 | if(!l) { | |
135 | controlreply(np, "Script %s is not loaded.", cargv[0]); | |
136 | return CMD_ERROR; | |
137 | } | |
138 | ||
139 | membefore+=lua_gc(l->l, LUA_GCCOUNT, 0); | |
140 | lua_gc(l->l, LUA_GCCOLLECT, 0); | |
141 | memafter+=lua_gc(l->l, LUA_GCCOUNT, 0); | |
142 | } | |
143 | controlreply(np, "Done."); | |
144 | controlreply(np, "Freed: %dKb (%0.2f%% of %dKb) -- %dKb now in use.", membefore - memafter, ((double)membefore - (double)memafter) / (double)membefore * 100, membefore, memafter); | |
145 | return CMD_OK; | |
146 | } |