mm_os 3.3.1 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/LICENSE +21 -201
  2. package/README.md +498 -99
  3. package/README_EN.md +505 -0
  4. package/adapter/adapter.js +431 -0
  5. package/adapter/custom_persistence.js +660 -0
  6. package/adapter/mqtt.js +273 -0
  7. package/adapter/socket.js +113 -0
  8. package/adapter/web.js +67 -0
  9. package/adapter/websocket.js +146 -0
  10. package/com/api/com.json +5 -0
  11. package/{core/com → com}/api/config.tpl.json +8 -8
  12. package/com/api/drive.js +708 -0
  13. package/com/api/index.js +198 -0
  14. package/com/api/oauth.js +200 -0
  15. package/com/api/script.tpl.js +32 -0
  16. package/com/cmd/README.md +11 -0
  17. package/com/cmd/com.json +5 -0
  18. package/com/cmd/config.tpl.json +122 -0
  19. package/com/cmd/drive.js +1548 -0
  20. package/com/cmd/index.js +1066 -0
  21. package/com/cmd/msg.json +48 -0
  22. package/com/cmd/nlp.js +525 -0
  23. package/com/cmd/script.tpl.js +32 -0
  24. package/com/db/com.json +5 -0
  25. package/com/db/drive.js +1999 -0
  26. package/com/db/index.js +242 -0
  27. package/{core/com → com}/event/README.md +4 -4
  28. package/com/event/com.json +5 -0
  29. package/{core/com → com}/event/config.tpl.json +18 -18
  30. package/com/event/drive.js +59 -0
  31. package/com/event/index.js +409 -0
  32. package/com/event/script.tpl.js +23 -0
  33. package/com/mqtt/com.json +5 -0
  34. package/{core/com → com}/mqtt/config.tpl.json +3 -5
  35. package/com/mqtt/drive.js +676 -0
  36. package/com/mqtt/index.js +822 -0
  37. package/com/mqtt/mm_mqtt.js +425 -0
  38. package/com/mqtt/script.tpl.js +723 -0
  39. package/com/nav/com.json +5 -0
  40. package/com/nav/config.tpl.json +84 -0
  41. package/com/nav/drive.js +702 -0
  42. package/com/nav/index.js +231 -0
  43. package/{core/com → com}/nav/tpl/admin_pc/page_config.vue +280 -280
  44. package/{core/com → com}/nav/tpl/admin_pc/page_config_form.vue +194 -194
  45. package/com/nav/tpl/admin_pc/page_form.vue +180 -0
  46. package/com/nav/tpl/admin_pc/page_view.vue +124 -0
  47. package/com/nav/tpl/dev_pc/page_default.vue +247 -0
  48. package/com/nav/tpl/dev_pc/page_type.vue +313 -0
  49. package/com/nav/tpl/home_pc/page_default.vue +234 -0
  50. package/com/nav/tpl/home_pc/page_form.vue +137 -0
  51. package/com/nav/tpl/home_pc/page_list.vue +234 -0
  52. package/com/nav/tpl/home_pc/page_nav.vue +221 -0
  53. package/com/nav/tpl/home_pc/page_type.vue +234 -0
  54. package/com/nav/tpl/home_pc/page_view.vue +125 -0
  55. package/com/nav/tpl/home_phone/page_channel.vue +234 -0
  56. package/com/nav/tpl/home_phone/page_default.vue +234 -0
  57. package/com/nav/tpl/home_phone/page_form.vue +137 -0
  58. package/com/nav/tpl/home_phone/page_nav.vue +237 -0
  59. package/com/nav/tpl/home_phone/page_type.vue +234 -0
  60. package/com/nav/tpl/home_phone/page_view.vue +125 -0
  61. package/com/nav/viewmodel.js +446 -0
  62. package/com/param/com.json +5 -0
  63. package/{core/com → com}/param/config.tpl.json +7 -1
  64. package/com/param/drive.js +502 -0
  65. package/com/param/index.js +155 -0
  66. package/com/param/script.tpl.js +12 -0
  67. package/com/pendant/com.json +5 -0
  68. package/{core/com/component → com/pendant}/config.tpl.json +15 -13
  69. package/com/pendant/drive.js +204 -0
  70. package/com/pendant/index.js +441 -0
  71. package/com/pendant/pendant.html +16 -0
  72. package/com/pendant/script.tpl.js +18 -0
  73. package/com/socket/com.json +5 -0
  74. package/com/socket/config.tpl.json +12 -0
  75. package/com/socket/drive.js +651 -0
  76. package/com/socket/index.js +351 -0
  77. package/com/socket/script.tpl.js +41 -0
  78. package/com/sql/com.json +5 -0
  79. package/{core/com → com}/sql/config.tpl.json +13 -9
  80. package/com/sql/drive.js +1259 -0
  81. package/com/sql/index.js +150 -0
  82. package/com/sql/script.tpl.js +47 -0
  83. package/com/static/com.json +5 -0
  84. package/{core/com → com}/static/config.tpl.json +10 -6
  85. package/com/static/drive.js +194 -0
  86. package/com/static/index.js +226 -0
  87. package/com/static/script.tpl.js +28 -0
  88. package/com/task/com.json +5 -0
  89. package/{core/com → com}/task/config.tpl.json +4 -6
  90. package/com/task/drive.js +405 -0
  91. package/com/task/index.js +148 -0
  92. package/com/task/script.tpl.js +37 -0
  93. package/com/template/com.json +5 -0
  94. package/com/template/config.tpl.json +16 -0
  95. package/com/template/drive.js +80 -0
  96. package/com/template/index.js +141 -0
  97. package/com.js +156 -0
  98. package/common/README.md +2 -0
  99. package/common/handler/msg/handler.json +22 -0
  100. package/common/handler/msg/index.js +23 -0
  101. package/common/handler/player/handler.json +22 -0
  102. package/common/handler/player/index.js +287 -0
  103. package/common/handler/user/handler.json +22 -0
  104. package/common/handler/user/index.js +23 -0
  105. package/common/middleware/web_after/index.js +29 -0
  106. package/common/middleware/web_after/middleware.json +9 -0
  107. package/common/middleware/web_base/index.js +113 -0
  108. package/common/middleware/web_base/middleware.json +19 -0
  109. package/common/middleware/web_before/index.js +33 -0
  110. package/common/middleware/web_before/middleware.json +9 -0
  111. package/common/middleware/web_cors/index.js +87 -0
  112. package/common/middleware/web_cors/middleware.json +24 -0
  113. package/common/middleware/web_error/index.js +119 -0
  114. package/common/middleware/web_error/middleware.json +18 -0
  115. package/common/middleware/web_ip/index.js +15 -0
  116. package/common/middleware/web_ip/middleware.json +14 -0
  117. package/common/middleware/web_logger/index.js +156 -0
  118. package/common/middleware/web_logger/middleware.json +14 -0
  119. package/common/middleware/web_main/index.js +24 -0
  120. package/common/middleware/web_main/middleware.json +9 -0
  121. package/common/middleware/web_static/index.js +73 -0
  122. package/common/middleware/web_static/middleware.json +54 -0
  123. package/common/middleware/web_waf/index.js +385 -0
  124. package/common/middleware/web_waf/middleware.json +13 -0
  125. package/common/model/msg/index.js +88 -0
  126. package/common/model/msg/model.json +401 -0
  127. package/common/model/player/index.js +63 -0
  128. package/common/model/player/model.json +185 -0
  129. package/common/model/user/index.js +11 -0
  130. package/common/model/user/model.json +219 -0
  131. package/core/app/config.tpl.json +67 -0
  132. package/core/app/index.js +632 -0
  133. package/core/app/script.tpl.js +52 -0
  134. package/core/channel/index.js +899 -0
  135. package/core/channel/matcher.js +585 -0
  136. package/core/com/config.tpl.json +16 -0
  137. package/core/com/index.js +74 -0
  138. package/core/com/script.tpl.js +5 -0
  139. package/core/component/component.js +42 -0
  140. package/core/component/config.tpl.json +63 -0
  141. package/core/component/index.js +273 -0
  142. package/core/component/script.tpl.js +19 -0
  143. package/core/controller/config.tpl.json +14 -0
  144. package/core/controller/index.js +373 -0
  145. package/core/controller/script.tpl.js +27 -0
  146. package/core/factory/config.tpl.json +14 -0
  147. package/core/factory/entity.js +275 -0
  148. package/core/factory/index.js +241 -0
  149. package/core/factory/script.tpl.js +16 -0
  150. package/core/game/bat/index.js +137 -0
  151. package/core/game/bat/world.js +622 -0
  152. package/core/game/config.tpl.json +16 -0
  153. package/core/game/entity_admin.js +230 -0
  154. package/core/game/index.js +186 -0
  155. package/core/handler/config.tpl.json +22 -0
  156. package/core/handler/index.js +181 -0
  157. package/core/handler/script.tpl.js +23 -0
  158. package/core/logic/config.tpl.json +14 -0
  159. package/core/logic/index.js +59 -0
  160. package/core/logic/script.tpl.js +19 -0
  161. package/core/middleware/config.tpl.json +16 -0
  162. package/core/middleware/index.js +125 -0
  163. package/core/middleware/script.tpl.js +37 -0
  164. package/core/mod/config.tpl.json +22 -0
  165. package/core/mod/index.js +130 -0
  166. package/core/mod/script.tpl.js +34 -0
  167. package/core/model/config.tpl.json +219 -0
  168. package/core/model/index.js +272 -0
  169. package/core/model/model.js +27 -0
  170. package/core/model/script.tpl.js +20 -0
  171. package/core/notifier/config.tpl.json +14 -0
  172. package/core/notifier/index.js +77 -0
  173. package/core/notifier/script.tpl.js +20 -0
  174. package/core/plugin/config.tpl.json +24 -0
  175. package/core/plugin/index.js +232 -0
  176. package/core/plugin/script.tpl.js +51 -0
  177. package/core/pusher/config.tpl.json +14 -0
  178. package/core/pusher/index.js +161 -0
  179. package/core/pusher/script.tpl.js +20 -0
  180. package/core/room/bat/index.js +170 -0
  181. package/core/room/bat/room.js +524 -0
  182. package/core/room/config.tpl.json +20 -0
  183. package/core/room/index.js +249 -0
  184. package/core/room/room.js +61 -0
  185. package/core/scene/config.tpl.json +14 -0
  186. package/core/scene/index.js +466 -0
  187. package/core/scene/loop.js +1255 -0
  188. package/core/scene/map.js +28 -0
  189. package/core/scene/script.tpl.js +22 -0
  190. package/core/sender/config.tpl.json +14 -0
  191. package/core/sender/index.js +79 -0
  192. package/core/sender/script.tpl.js +20 -0
  193. package/core/service/config.tpl.json +14 -0
  194. package/core/service/index.js +100 -0
  195. package/core/service/script.tpl.js +25 -0
  196. package/core/store/config.tpl.json +26 -0
  197. package/core/store/index.js +1755 -0
  198. package/core/store/script.tpl.js +22 -0
  199. package/core/store/sql.js +1464 -0
  200. package/core/system/config.tpl.json +18 -0
  201. package/core/system/index.js +312 -0
  202. package/core/system/script.tpl.js +77 -0
  203. package/core/view/config.tpl.json +14 -0
  204. package/core/view/index.js +91 -0
  205. package/core/view/script.tpl.js +20 -0
  206. package/core/zone/bat/index.js +725 -0
  207. package/core/zone/config.tpl.json +54 -0
  208. package/core/zone/index.js +614 -0
  209. package/core/zone/script.tpl.js +10 -0
  210. package/core/zone/zone_bat.js +136 -0
  211. package/core//345/237/272/347/261/273/346/250/241/345/235/227/346/270/205/345/215/225.md +24 -0
  212. package/index.js +17 -333
  213. package/os.js +57 -0
  214. package/package.json +65 -55
  215. package/server.js +598 -0
  216. package/README.en.md +0 -36
  217. package/conf.json +0 -3
  218. package/core/base/mqtt/index.js +0 -1110
  219. package/core/base/mqtt/lib.js +0 -40
  220. package/core/base/web/index.js +0 -245
  221. package/core/com/api/com.json +0 -4
  222. package/core/com/api/drive.js +0 -668
  223. package/core/com/api/index.js +0 -108
  224. package/core/com/api/oauth.js +0 -158
  225. package/core/com/api/script.js +0 -32
  226. package/core/com/app/README.md +0 -3
  227. package/core/com/app/com.json +0 -4
  228. package/core/com/app/config.tpl.json +0 -16
  229. package/core/com/app/drive.js +0 -309
  230. package/core/com/app/index.js +0 -211
  231. package/core/com/app/script.js +0 -155
  232. package/core/com/cmd/com.json +0 -4
  233. package/core/com/cmd/config.tpl.json +0 -66
  234. package/core/com/cmd/drive.js +0 -513
  235. package/core/com/cmd/index.js +0 -354
  236. package/core/com/cmd/old/5w2h.js +0 -54
  237. package/core/com/cmd/old/drive.js +0 -423
  238. package/core/com/cmd/script.js +0 -11
  239. package/core/com/component/README.md +0 -3
  240. package/core/com/component/com.json +0 -4
  241. package/core/com/component/component.html +0 -16
  242. package/core/com/component/drive.js +0 -197
  243. package/core/com/component/index.js +0 -312
  244. package/core/com/component/script.js +0 -18
  245. package/core/com/db/com.json +0 -4
  246. package/core/com/db/drive.js +0 -1160
  247. package/core/com/db/index.js +0 -176
  248. package/core/com/event/com.json +0 -4
  249. package/core/com/event/drive.js +0 -133
  250. package/core/com/event/index.js +0 -345
  251. package/core/com/event/script.js +0 -26
  252. package/core/com/eventer/com.js +0 -477
  253. package/core/com/eventer/com.json +0 -4
  254. package/core/com/middleware/com.js +0 -154
  255. package/core/com/middleware/com.json +0 -4
  256. package/core/com/middleware/config.tpl.json +0 -8
  257. package/core/com/middleware/script.js +0 -9
  258. package/core/com/mqtt/com.json +0 -4
  259. package/core/com/mqtt/drive.js +0 -600
  260. package/core/com/mqtt/index.js +0 -572
  261. package/core/com/mqtt/mm_mqtt.js +0 -330
  262. package/core/com/mqtt/script.js +0 -604
  263. package/core/com/msg/com.js +0 -296
  264. package/core/com/msg/com.json +0 -4
  265. package/core/com/nav/com.json +0 -4
  266. package/core/com/nav/config.tpl.json +0 -75
  267. package/core/com/nav/drive.js +0 -549
  268. package/core/com/nav/index.js +0 -182
  269. package/core/com/nav/tpl/admin_pc/page_form.vue +0 -180
  270. package/core/com/nav/tpl/admin_pc/page_view.vue +0 -124
  271. package/core/com/nav/tpl/dev_pc/page_default.vue +0 -247
  272. package/core/com/nav/tpl/dev_pc/page_type.vue +0 -313
  273. package/core/com/nav/tpl/home_pc/page_default.vue +0 -234
  274. package/core/com/nav/tpl/home_pc/page_form.vue +0 -137
  275. package/core/com/nav/tpl/home_pc/page_list.vue +0 -234
  276. package/core/com/nav/tpl/home_pc/page_nav.vue +0 -221
  277. package/core/com/nav/tpl/home_pc/page_type.vue +0 -234
  278. package/core/com/nav/tpl/home_pc/page_view.vue +0 -125
  279. package/core/com/nav/tpl/home_phone/page_channel.vue +0 -234
  280. package/core/com/nav/tpl/home_phone/page_default.vue +0 -234
  281. package/core/com/nav/tpl/home_phone/page_form.vue +0 -137
  282. package/core/com/nav/tpl/home_phone/page_nav.vue +0 -237
  283. package/core/com/nav/tpl/home_phone/page_type.vue +0 -234
  284. package/core/com/nav/tpl/home_phone/page_view.vue +0 -125
  285. package/core/com/nav/viewmodel.js +0 -296
  286. package/core/com/param/drive.js +0 -366
  287. package/core/com/param/index.js +0 -80
  288. package/core/com/param/script.js +0 -12
  289. package/core/com/param/test.js +0 -98
  290. package/core/com/plugin/README.md +0 -3
  291. package/core/com/plugin/com.json +0 -4
  292. package/core/com/plugin/config.tpl.json +0 -26
  293. package/core/com/plugin/drive.js +0 -536
  294. package/core/com/plugin/index.js +0 -259
  295. package/core/com/plugin/script.js +0 -213
  296. package/core/com/rpc/com.json +0 -4
  297. package/core/com/rpc/drive.js +0 -160
  298. package/core/com/rpc/index.js +0 -87
  299. package/core/com/rpc/rpc.js +0 -118
  300. package/core/com/socket/com.json +0 -4
  301. package/core/com/socket/config.tpl.json +0 -14
  302. package/core/com/socket/drive.js +0 -403
  303. package/core/com/socket/index.js +0 -62
  304. package/core/com/socket/script.js +0 -42
  305. package/core/com/sql/drive.js +0 -1087
  306. package/core/com/sql/index.js +0 -83
  307. package/core/com/sql/script.js +0 -48
  308. package/core/com/static/com.json +0 -4
  309. package/core/com/static/drive.js +0 -220
  310. package/core/com/static/index.js +0 -149
  311. package/core/com/static/script.js +0 -28
  312. package/core/com/task/com.json +0 -4
  313. package/core/com/task/drive.js +0 -403
  314. package/core/com/task/index.js +0 -110
  315. package/core/com/task/script.js +0 -37
  316. package/core/com/timer/com.js +0 -217
  317. package/core/com/timer/com.json +0 -4
  318. package/core/com/tpl/com.js +0 -19
  319. package/core/com/tpl/com.json +0 -4
  320. package/lib/actions.js +0 -50
  321. package/lib/base.js +0 -361
  322. package/lib/com.js +0 -29
  323. package/lib/ref.js +0 -121
  324. package/middleware/cors/index.js +0 -119
  325. package/middleware/cors/middleware.json +0 -20
  326. package/middleware/csrf/index.js +0 -202
  327. package/middleware/csrf/middleware.json +0 -24
  328. package/middleware/ip_firewall/index.js +0 -476
  329. package/middleware/ip_firewall/middleware.json +0 -109
  330. package/middleware/mqtt_base/index.js +0 -10
  331. package/middleware/mqtt_base/middleware.json +0 -11
  332. package/middleware/security_audit/index.js +0 -543
  333. package/middleware/security_audit/middleware.json +0 -48
  334. package/middleware/waf/index.js +0 -343
  335. package/middleware/waf/middleware.json +0 -10
  336. package/middleware/waf_ddos/index.js +0 -520
  337. package/middleware/waf_ddos/middleware.json +0 -38
  338. package/middleware/waf_xss/index.js +0 -269
  339. package/middleware/waf_xss/middleware.json +0 -18
  340. package/middleware/web_after/index.js +0 -33
  341. package/middleware/web_after/middleware.json +0 -10
  342. package/middleware/web_base/index.js +0 -90
  343. package/middleware/web_base/middleware.json +0 -10
  344. package/middleware/web_before/index.js +0 -27
  345. package/middleware/web_before/middleware.json +0 -10
  346. package/middleware/web_check/index.js +0 -28
  347. package/middleware/web_check/middleware.json +0 -10
  348. package/middleware/web_main/index.js +0 -28
  349. package/middleware/web_main/middleware.json +0 -10
  350. package/middleware/web_proxy/index.js +0 -37
  351. package/middleware/web_proxy/middleware.json +0 -10
  352. package/middleware/web_render/index.js +0 -87
  353. package/middleware/web_render/middleware.json +0 -10
  354. package/middleware/web_socket/index.js +0 -34
  355. package/middleware/web_socket/middleware.json +0 -10
  356. package/middleware/web_static/index.js +0 -115
  357. package/middleware/web_static/middleware.json +0 -10
  358. /package/{core/com → com}/api/README.md +0 -0
  359. /package/{core/com → com}/db/README.md +0 -0
  360. /package/{core/com → com}/mqtt/README.md +0 -0
  361. /package/{core/com → com}/nav/README.md +0 -0
  362. /package/{core/com → com}/nav/tpl/admin_pc/page_channel.vue +0 -0
  363. /package/{core/com → com}/nav/tpl/admin_pc/page_default.vue +0 -0
  364. /package/{core/com → com}/nav/tpl/admin_pc/page_lang.vue +0 -0
  365. /package/{core/com → com}/nav/tpl/admin_pc/page_nav.vue +0 -0
  366. /package/{core/com → com}/nav/tpl/admin_pc/page_table.vue +0 -0
  367. /package/{core/com → com}/nav/tpl/admin_pc/page_type.vue +0 -0
  368. /package/{core/com → com}/nav/tpl/dev_pc/page_channel.vue +0 -0
  369. /package/{core/com → com}/nav/tpl/dev_pc/page_config.vue +0 -0
  370. /package/{core/com → com}/nav/tpl/dev_pc/page_form.vue +0 -0
  371. /package/{core/com → com}/nav/tpl/dev_pc/page_nav.vue +0 -0
  372. /package/{core/com → com}/nav/tpl/dev_pc/page_table.vue +0 -0
  373. /package/{core/com → com}/nav/tpl/home_pc/page_channel.vue +0 -0
  374. /package/{core/com → com}/nav/tpl/home_phone/page_list.vue +0 -0
  375. /package/{core/com → com}/param/README.md +0 -0
  376. /package/{core/com/cmd → com/pendant}/README.md +0 -0
  377. /package/{core/com → com}/socket/README.md +0 -0
  378. /package/{core/com → com}/sql/README.md +0 -0
  379. /package/{core/com → com}/static/README.md +0 -0
  380. /package/{core/com → com}/task/README.md +0 -0
@@ -0,0 +1,373 @@
1
+ const {
2
+ Drive
3
+ } = require('mm_machine');
4
+ const { idGen } = require('../../ulits/id_gen.js');
5
+
6
+ /**
7
+ * 控制器基类
8
+ * 负责处理请求和响应
9
+ */
10
+ class Controller extends Drive {
11
+ static config = {
12
+ name: 'default',
13
+ // 依赖的处理器
14
+ ctrl_list: [],
15
+ timeout: 30000,
16
+ perf_log: false, // 是否记录性能日志
17
+ };
18
+
19
+ /**
20
+ * 构造函数
21
+ * @param {object} config 配置参数
22
+ * @param {object} parent 父对象
23
+ */
24
+ constructor(config, parent) {
25
+ super({ ...Controller.config, ...config || {} }, parent);
26
+ // 模型实例集合
27
+ this._model = {};
28
+ // 服务实例集合
29
+ this._service = {};
30
+ // 视图实例集合
31
+ this._view = {};
32
+ }
33
+ }
34
+
35
+ /**
36
+ * 预设
37
+ */
38
+ Controller.prototype._preset = function () {
39
+ // 响应格式缓存对象
40
+ this._response_cache = {
41
+ error: {
42
+ code: 0,
43
+ message: '',
44
+ },
45
+ result: null
46
+ };
47
+ // 统计信息
48
+ this._stats = {
49
+ request_count: 0,
50
+ all_time: 0
51
+ };
52
+ };
53
+
54
+ /**
55
+ * 获取模板目录
56
+ * @returns {string} 模板目录
57
+ */
58
+ Controller.prototype.getTplDir = function () {
59
+ return __dirname;
60
+ };
61
+
62
+ /**
63
+ * 初始化核心
64
+ * @param {object} model 模型实例集合
65
+ * @param {object} service 服务实例集合
66
+ * @param {object} view 视图实例集合
67
+ * @param {object} eventer 事件总线
68
+ * @param {object} logger 日志管理器
69
+ */
70
+ Controller.prototype._initCore = async function (model, service, view, eventer, logger) {
71
+ // 初始化依赖项
72
+ if (logger) {
73
+ this.setLogger(logger);
74
+ }
75
+ if (eventer) {
76
+ this.getEventer = function () {
77
+ return eventer;
78
+ };
79
+ }
80
+ if (model) this._model = model;
81
+ if (service) this._service = service;
82
+ if (view) this._view = view;
83
+
84
+ // 验证依赖项
85
+ this._checkDeps();
86
+ };
87
+
88
+ /**
89
+ * 验证依赖项
90
+ */
91
+ Controller.prototype._checkDeps = function () {
92
+ var { models, services, views } = this.config;
93
+
94
+ for (let name of models) {
95
+ if (!this._model[name]) {
96
+ this.log('error', `model ${name} not found`);
97
+ }
98
+ }
99
+
100
+ for (let name of services) {
101
+ if (!this._service[name]) {
102
+ this.log('error', `service ${name} not found`);
103
+ }
104
+ }
105
+
106
+ for (let name of views) {
107
+ if (!this._view[name]) {
108
+ this.log('error', `view ${name} not found`);
109
+ }
110
+ }
111
+ };
112
+
113
+
114
+ /**
115
+ * 启动处理器
116
+ * @returns {Promise<void>}
117
+ * @throws {Error} 启动失败时抛出异常
118
+ */
119
+ Controller.prototype._start = async function () {
120
+ // 记录启动日志
121
+ this.log('info', 'started');
122
+ };
123
+
124
+ /**
125
+ * 停止处理器
126
+ * @returns {Promise<void>}
127
+ * @throws {Error} 停止失败时抛出异常
128
+ */
129
+ Controller.prototype._stop = async function () {
130
+ // 记录停止日志
131
+ this.log('info', 'stopped');
132
+ };
133
+
134
+ /**
135
+ * 销毁处理器
136
+ * @returns {Promise<void>}
137
+ * @throws {Error} 销毁失败时抛出异常
138
+ */
139
+ Controller.prototype._destroy = async function () {
140
+ this._stats = {
141
+ request_count: 0,
142
+ all_time: 0
143
+ };
144
+
145
+ // 移除所有监听器
146
+ this.removeAllListeners();
147
+ };
148
+
149
+ /**
150
+ * 创建处理Promise
151
+ * @param {object} req 请求对象
152
+ * @param {object} res 响应对象
153
+ * @param {object} event_context 事件上下文
154
+ * @returns {Promise<object>} 处理结果Promise
155
+ */
156
+ Controller.prototype._createRun = async function (req, res, event_context) {
157
+ // 请求预处理
158
+ await this._before(req, res);
159
+
160
+ // 触发主处理开始事件
161
+ this.emitEvent('request:before', event_context);
162
+
163
+ // 请求主处理逻辑
164
+ let result = await this.main(req, res);
165
+ const UPDATED_CONTEXT = {
166
+ ...event_context,
167
+ result
168
+ };
169
+
170
+ // 触发主处理完成事件
171
+ this.emitEvent('request:after', UPDATED_CONTEXT);
172
+
173
+ // 请求后处理
174
+ await this._after(req, res, result);
175
+
176
+ return result;
177
+ };
178
+
179
+ /**
180
+ * 创建超时Promise
181
+ * @param {number} timeout 超时时间
182
+ * @returns {Promise<object>} 超时Promise
183
+ */
184
+ Controller.prototype._createTimeout = function (timeout) {
185
+ return new Promise((resolve, reject) => {
186
+ this.log('debug', '创建超时控制Promise', { timeout, resolve, reject });
187
+ let timer = setTimeout(() => {
188
+ const timeoutError = new Error(`Request timeout after ${timeout}ms`);
189
+ timeoutError.code = 408;
190
+ reject(timeoutError);
191
+ }, timeout);
192
+ timer.unref(); // 防止定时器阻止进程退出
193
+ });
194
+ };
195
+
196
+ /**
197
+ * 处理性能统计
198
+ * @param {Array} start_time 开始时间
199
+ * @param {object} event_context 事件上下文
200
+ * @returns {object} 更新后的事件上下文
201
+ */
202
+ Controller.prototype._runPerfStats = function (start_time, event_context) {
203
+ // 性能统计结束
204
+ let diff = process.hrtime(start_time);
205
+ const TIME_MS = diff[0] * 1000 + diff[1] / 1e6;
206
+ this._stats.all_time += TIME_MS;
207
+
208
+ // 创建更新的事件上下文
209
+ const UPDATED_CONTEXT = {
210
+ ...event_context,
211
+ process_time: TIME_MS
212
+ };
213
+
214
+ // 记录性能日志(如果开启)
215
+ if (this.config.perf_log) {
216
+ this.log('info',
217
+ `request processed in ${TIME_MS.toFixed(2)}ms`
218
+ );
219
+ }
220
+
221
+ return UPDATED_CONTEXT;
222
+ };
223
+
224
+ /**
225
+ * 验证请求参数
226
+ * @param {object} req 请求对象
227
+ * @param {object} res 响应对象
228
+ */
229
+ Controller.prototype._validateReq = function (req, res) {
230
+ if (!req || typeof req !== 'object') {
231
+ throw new TypeError('请求对象不能为空且必须是对象');
232
+ }
233
+ if (!res || typeof res !== 'object') {
234
+ throw new TypeError('响应对象不能为空且必须是对象');
235
+ }
236
+ };
237
+
238
+ /**
239
+ * 创建事件上下文
240
+ * @param {object} req 请求对象
241
+ * @param {object} res 响应对象
242
+ * @returns {object} 事件上下文
243
+ */
244
+ Controller.prototype._createEventContext = function (req, res) {
245
+ return {
246
+ request_id: req.id || idGen.genId('req'),
247
+ hdl_name: this.config.name,
248
+ req,
249
+ res
250
+ };
251
+ };
252
+
253
+ /**
254
+ * 处理请求主方法
255
+ * @param {object} req 请求对象
256
+ * @param {object} res 响应对象
257
+ * @returns {Promise<object>} 处理结果
258
+ */
259
+ Controller.prototype.run = async function (req, res) {
260
+ this._validateReq(req, res);
261
+ var event_context = this._createEventContext(req, res);
262
+ this.emitEvent('request:before', event_context);
263
+ var start_time = process.hrtime();
264
+ this._stats.request_count++;
265
+
266
+ try {
267
+ var result = await this._execWithTimeout(req, res, event_context);
268
+ var response = this._formatResponse(result);
269
+ event_context.response = response;
270
+ this.emitEvent('request:success', event_context);
271
+ return response;
272
+ } catch (error) {
273
+ event_context.error = error;
274
+ this.emitEvent('request:error', event_context);
275
+ this.log('error', 'handle error:', error);
276
+ return this._formatError(error);
277
+ } finally {
278
+ var final_context = this._runPerfStats(start_time, event_context);
279
+ this.emitEvent('request:after', final_context);
280
+ }
281
+ };
282
+
283
+ /**
284
+ * 执行带超时的处理
285
+ * @param {object} req 请求对象
286
+ * @param {object} res 响应对象
287
+ * @param {object} event_context 事件上下文
288
+ * @returns {Promise<object>} 处理结果
289
+ */
290
+ Controller.prototype._execWithTimeout = async function (req, res, event_context) {
291
+ var timeout = this.config.timeout;
292
+ var hdl_promise = this._createRun(req, res, event_context);
293
+ if (timeout > 0) {
294
+ var timeout_promise = this._createTimeout(timeout);
295
+ return await Promise.race([hdl_promise, timeout_promise]);
296
+ }
297
+ return await hdl_promise;
298
+ };
299
+
300
+ /**
301
+ * 请求预处理方法
302
+ * @param {object} req 请求对象
303
+ * @param {object} res 响应对象
304
+ * @returns {Promise<void>}
305
+ */
306
+ Controller.prototype._before = async function (req, res) {
307
+ this.log('debug', '请求预处理', { req, res });
308
+ };
309
+
310
+ /**
311
+ * 请求主处理逻辑
312
+ * 核心业务逻辑应该在此方法中实现
313
+ * @param {object} req 请求对象
314
+ * @param {object} res 响应对象
315
+ * @returns {Promise<object>} 处理结果
316
+ */
317
+ Controller.prototype.main = async function (req, res) {
318
+ this.log('debug', '默认请求处理,子类应重写此方法', { req, res });
319
+ // 默认实现,子类必须重写
320
+ throw new Error('main method must be overridden');
321
+ };
322
+
323
+ /**
324
+ * 请求后处理方法
325
+ * @param {object} req 请求对象
326
+ * @param {object} res 响应对象
327
+ * @param {object} result 处理结果
328
+ * @returns {Promise<void>}
329
+ */
330
+ Controller.prototype._after = async function (req, res, result) {
331
+ this.log('debug', '请求后处理', { req, res, result });
332
+ // 后处理请求,不触发额外事件
333
+ };
334
+
335
+ /**
336
+ * 格式化响应
337
+ * 优化:复用响应对象,减少GC压力
338
+ * @param {number} code 响应码
339
+ * @param {string} message 响应消息
340
+ * @param {object} data 响应数据
341
+ * @returns {object} 格式化后的响应对象
342
+ */
343
+ Controller.prototype._formatResponse = function (result) {
344
+ // 返回新对象,避免外部修改影响缓存
345
+ return $.ret.ret(result);
346
+ };
347
+
348
+ /**
349
+ * 格式化错误响应
350
+ * @param {object} error 错误对象
351
+ * @returns {object} 格式化后的错误响应
352
+ */
353
+ Controller.prototype._formatError = function (error) {
354
+ // 快速错误处理,减少属性访问
355
+ let code = error && error.code || 500;
356
+ let message = error && error.message || 'Internal Server Error';
357
+ return $.ret.error(code, message);
358
+ };
359
+
360
+ /**
361
+ * 获取性能统计信息
362
+ * @returns {object} 性能统计数据
363
+ */
364
+ Controller.prototype.getStats = function () {
365
+ return {
366
+ request_count: this._stats.request_count,
367
+ all_time: this._stats.all_time,
368
+ average_time: this._stats.request_count > 0 ?
369
+ this._stats.all_time / this._stats.request_count : 0
370
+ };
371
+ };
372
+
373
+ exports.Controller = Controller;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * 控制器,主要用于处理请求和响应
3
+ */
4
+ module.exports = {
5
+ /**
6
+ * 初始化
7
+ * @param {object} model 模型
8
+ * @param {object} service 服务
9
+ * @param {object} view 视图
10
+ * @param {object} eventer 事件总线
11
+ */
12
+ async _init(model, service, view, eventer) {
13
+ this.log('debug', '控制器初始化');
14
+ // 初始化代码写在这
15
+ },
16
+ /**
17
+ * 主要逻辑
18
+ * @param {object} ctx 上下文
19
+ * @param {object} db 数据库
20
+ * @returns {Promise} 返回一个Promise对象
21
+ */
22
+ async main(ctx, db) {
23
+ this.log('debug', '控制器主要逻辑', { ctx, db });
24
+ // 主要代码写在这
25
+ return 'Hello world!';
26
+ }
27
+ };
@@ -0,0 +1,14 @@
1
+ {
2
+ // 名称
3
+ "name": "${name}",
4
+ // 标题
5
+ "title": "${title || '角色工厂'}",
6
+ // 描述
7
+ "description": "${description || '用于创建和管理角色的工厂'}",
8
+ // 主文件
9
+ "main": "${main || 'index.js'}",
10
+ // 状态 0:禁用 1:启用
11
+ "state": 1,
12
+ // 排序,越小越靠前
13
+ "sort": 100
14
+ }
@@ -0,0 +1,275 @@
1
+ /**
2
+ * 实体类
3
+ * 纯粹的实体标识符,不包含任何业务逻辑
4
+ * 只负责管理组件引用和实体生命周期
5
+ */
6
+ const { idGen } = require('../../ulits/id_gen.js');
7
+ class Entity {
8
+ #is_dirty = false;
9
+
10
+ /**
11
+ * 构造函数
12
+ * @param {string} entity_id 实体ID
13
+ * @param {string} player_id 玩家ID
14
+ * @param {string} type 实体类型, 例如:玩家player、怪物monster、道具prop等
15
+ */
16
+ constructor(entity_id, player_id, type) {
17
+ // 实体名称
18
+ this.name = '';
19
+ // 实体ID
20
+ this.entity_id = entity_id || this.genId();
21
+ // 实体类型
22
+ this.type = type || '';
23
+ // 玩家ID - 如果是玩家就有此ID
24
+ this.player_id = player_id || '';
25
+ // 是否活跃
26
+ this.is_active = true;
27
+ // 实体组件
28
+ this._component = new Map();
29
+
30
+ // 创建属性代理
31
+ this._createProperty();
32
+ }
33
+
34
+ /**
35
+ * 检查实体是否脏数据
36
+ * @param {boolean} is_dirty 是否脏数据
37
+ * @returns {boolean} 是否脏数据
38
+ */
39
+ isDirty(is_dirty) {
40
+ if (is_dirty !== undefined) {
41
+ this.#is_dirty = is_dirty;
42
+ }
43
+ return this.#is_dirty;
44
+ };
45
+ }
46
+
47
+ /**
48
+ * 创建属性代理
49
+ * 使组件属性可以通过点语法直接访问
50
+ * 例如:entity.attr.hp 可以访问 attr 组件中的 hp 属性
51
+ */
52
+ Entity.prototype._createProperty = function () {
53
+ var self = this;
54
+
55
+ // 为每个已存在的组件创建属性访问器
56
+ var keys = Array.from(self._component.keys());
57
+ for (var i = 0; i < keys.length; i++) {
58
+ (function (name) {
59
+ Object.defineProperty(self, name, {
60
+ get: function () {
61
+ return self._component.get(name);
62
+ },
63
+ set: function (value) {
64
+ if (typeof value === 'object' && value !== null) {
65
+ self._component.set(name, value);
66
+ // 标记为脏数据
67
+ self.isDirty(true);
68
+ }
69
+ },
70
+ enumerable: true,
71
+ configurable: true
72
+ });
73
+ })(keys[i]);
74
+ }
75
+
76
+ // 重写 addComponent 方法,使其在添加组件时自动创建属性访问器
77
+ let comp = self.addComponent;
78
+ self.addComponent = function (name, component) {
79
+ // 调用原始方法
80
+ comp.call(self, name, component);
81
+
82
+ // 创建属性访问器
83
+ Object.defineProperty(self, name, {
84
+ get: function () {
85
+ return self._component.get(name);
86
+ },
87
+ set: function (value) {
88
+ if (typeof value === 'object' && value !== null) {
89
+ self._component.set(name, value);
90
+ // 标记为脏数据
91
+ self.isDirty(true);
92
+ }
93
+ },
94
+ enumerable: true,
95
+ configurable: true
96
+ });
97
+ };
98
+ };
99
+
100
+ /**
101
+ * 获取实体ID
102
+ * @returns {string} 实体ID
103
+ */
104
+ Entity.prototype.getId = function () {
105
+ return this.entity_id;
106
+ };
107
+
108
+ /**
109
+ * 检查实体是否活跃
110
+ * @returns {boolean} 是否活跃
111
+ */
112
+ Entity.prototype.isActive = function () {
113
+ return this.is_active;
114
+ };
115
+
116
+ /**
117
+ * 激活实体
118
+ */
119
+ Entity.prototype.activate = function () {
120
+ this.is_active = true;
121
+ };
122
+
123
+ /**
124
+ * 停用实体
125
+ */
126
+ Entity.prototype.deactivate = function () {
127
+ this.is_active = false;
128
+ };
129
+
130
+ /**
131
+ * 添加组件
132
+ * @param {string} name 组件类型
133
+ * @param {object} component 组件数据
134
+ */
135
+ Entity.prototype.addComponent = function (name, component) {
136
+ // 参数校验
137
+ if (typeof name !== 'string') {
138
+ throw new TypeError('组件类型必须是字符串');
139
+ }
140
+
141
+ if (typeof component !== 'object') {
142
+ throw new TypeError('组件数据必须是对象');
143
+ }
144
+ this._component.set(name, component);
145
+ };
146
+
147
+ /**
148
+ * 获取组件
149
+ * @param {string} name 组件类型
150
+ * @returns {object|null} 组件数据
151
+ */
152
+ Entity.prototype.getComponent = function (name) {
153
+ // 参数校验
154
+ if (typeof name !== 'string') {
155
+ throw new TypeError('组件类型必须是字符串');
156
+ }
157
+ return this._component.get(name) || null;
158
+ };
159
+
160
+ /**
161
+ * 检查是否包含组件
162
+ * @param {string} name 组件类型
163
+ * @returns {boolean} 是否包含组件
164
+ */
165
+ Entity.prototype.hasComponent = function (name) {
166
+ // 参数校验
167
+ if (typeof name !== 'string') {
168
+ throw new TypeError('组件类型必须是字符串');
169
+ }
170
+ return this._component.has(name);
171
+ };
172
+
173
+ /**
174
+ * 移除组件
175
+ * @param {string} name 组件类型
176
+ * @returns {boolean} 是否移除成功
177
+ */
178
+ Entity.prototype.delComponent = function (name) {
179
+ // 参数校验
180
+ if (typeof name !== 'string') {
181
+ throw new TypeError('组件类型必须是字符串');
182
+ }
183
+ return this._component.delete(name);
184
+ };
185
+
186
+ /**
187
+ * 获取所有组件类型
188
+ * @returns {Array} 组件类型数组
189
+ */
190
+ Entity.prototype.getComponentTypes = function () {
191
+ return Array.from(this._component.keys());
192
+ };
193
+
194
+ /**
195
+ * 转换为JSON字符串
196
+ * @returns {string} JSON字符串
197
+ */
198
+ Entity.prototype.toJson = function () {
199
+ let data = {
200
+ entity_id: this.entity_id,
201
+ player_id: this.player_id,
202
+ is_active: this.is_active,
203
+ name: this.name,
204
+ type: this.type,
205
+ components: Object.fromEntries(this._component)
206
+ };
207
+ return JSON.stringify(data);
208
+ };
209
+
210
+ /**
211
+ * 从JSON字符串解析实体
212
+ * @param {string} json_str JSON字符串
213
+ * @returns {Entity} 实体对象
214
+ */
215
+ Entity.prototype.fromJson = function (json_str) {
216
+ // 参数校验
217
+ if (typeof json_str !== 'string') {
218
+ throw new TypeError('JSON字符串必须是字符串');
219
+ }
220
+ let data = JSON.parse(json_str);
221
+
222
+ if (!data.entity_id) {
223
+ throw new Error('JSON字符串缺少实体ID');
224
+ }
225
+
226
+ // 设置基本属性
227
+ this.entity_id = data.entity_id;
228
+ this.player_id = data.player_id || '';
229
+ this.is_active = data.is_active !== undefined ? data.is_active : true;
230
+ this.name = data.name || '';
231
+ this.type = data.type || '';
232
+
233
+ // 恢复组件
234
+ if (data.components && typeof data.components === 'object') {
235
+ for (var k in data.components) {
236
+ this.addComponent(k, data.components[k]);
237
+ }
238
+ // 创建属性访问器
239
+ this._createProperty();
240
+ }
241
+
242
+ return this;
243
+ };
244
+
245
+ /**
246
+ * 生成唯一实体ID
247
+ * @returns {string} 唯一实体ID
248
+ */
249
+ Entity.prototype.genId = function () {
250
+ return idGen.genId('entity');
251
+ };
252
+
253
+ /**
254
+ * 设置实体模型
255
+ * @param {object} model 实体模型
256
+ */
257
+ Entity.prototype.setModel = function (model) {
258
+ for (var k in model) {
259
+ let value = model[k];
260
+ if (typeof value === 'object') {
261
+ var component = this.getComponent(k);
262
+ if (component) {
263
+ $.push(component, value);
264
+ this.addComponent(k, component);
265
+ }
266
+ }
267
+ else if (this.hasOwnProperty(k)) {
268
+ this[k] = value;
269
+ }
270
+ }
271
+ };
272
+
273
+ module.exports = {
274
+ Entity
275
+ };