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,622 @@
1
+ const {
2
+ Drive,
3
+ Manager
4
+ } = require('mm_machine');
5
+ const {
6
+ Scene
7
+ } = require('../../scene/index.js');
8
+ const {
9
+ System
10
+ } = require('../../system/index.js');
11
+ const {
12
+ Logic
13
+ } = require('../../logic/index.js');
14
+ const {
15
+ Factory
16
+ } = require('../../factory/index.js');
17
+ const {
18
+ Component
19
+ } = require('../../component/index.js');
20
+ const {
21
+ EntityAdmin
22
+ } = require('../entity_admin.js');
23
+ const {
24
+ GameLoop
25
+ } = require('../../scene/loop.js');
26
+ const {
27
+ idGen
28
+ } = require('../../../ulits/id_gen.js');
29
+
30
+ /**
31
+ * 游戏世界
32
+ */
33
+ class GameWorld extends Drive {
34
+ static config = {
35
+ // 游戏名称
36
+ 'name': 'world',
37
+ // 游戏标题
38
+ 'title': '游戏世界',
39
+ // 游戏描述
40
+ 'description': '这是一个游戏世界',
41
+ // 游戏主脚本 - 可自定义游戏初始化,一般情况不需要定义
42
+ 'main': '',
43
+ // 游戏状态 - 1 正常 0 禁用
44
+ 'state': 1,
45
+ // 游戏排序 - 数字越小越靠前
46
+ 'sort': 100,
47
+ // 游戏类型 - 角色扮演rpg、卡牌游戏card、策略游戏strategy、模拟经营simulation
48
+ 'type': 'rpg',
49
+ // 游戏实体类型 - 玩家player、NPC、怪物、物品等
50
+ 'entity_type': 'player'
51
+ };
52
+
53
+ /**
54
+ * 构造函数
55
+ * @param {object} config 配置参数
56
+ */
57
+ constructor(config = {}) {
58
+ super({ ...GameWorld.config, ...config });
59
+
60
+ // 游戏世界ID
61
+ this.world_id = this.genId();
62
+ // 玩家ID集合 - 使用Set保证唯一性和高效查找
63
+ this._player_ids = new Set();
64
+
65
+ // 游戏实体
66
+ this.entities = new Map();
67
+
68
+ // 实体管理器
69
+ this.entityAdmin = null;
70
+ // 游戏循环
71
+ this.loop = null;
72
+
73
+ // 游戏场景集合
74
+ this.scene = {};
75
+ // 游戏系统集合
76
+ this.system = {};
77
+ // 游戏逻辑集合
78
+ this.logic = {};
79
+ // 游戏工厂集合
80
+ this.factory = {};
81
+ // 游戏组件集合
82
+ this.component = {};
83
+
84
+ // 管理器集合
85
+ this.manager = {};
86
+ }
87
+ }
88
+
89
+ /**
90
+ * 获取模板目录
91
+ * @returns {string} 模板目录
92
+ */
93
+ GameWorld.prototype.getTplDir = function () {
94
+ return __dirname;
95
+ };
96
+
97
+ /**
98
+ * 获取游戏管理器目录
99
+ * @returns {string} 游戏管理器目录
100
+ */
101
+ GameWorld.prototype._getDir = function () {
102
+ return this.getGame()._
103
+ };
104
+
105
+ /**
106
+ * 生成游戏世界ID
107
+ * @returns {string} 游戏世界ID
108
+ */
109
+ GameWorld.prototype.genId = function () {
110
+ return idGen.genId('world');
111
+ };
112
+
113
+ /**
114
+ * 创建管理器实例
115
+ * @param {string} name 管理器名称
116
+ * @param {string} title 管理器标题
117
+ * @param {Function} cls 管理器类
118
+ * @returns {object} 管理器实例
119
+ */
120
+ GameWorld.prototype._createManager = function (name, title, cls) {
121
+ var dir = this._getDir();
122
+ var manager = new Manager({
123
+ name,
124
+ title,
125
+ scope: this.config.name,
126
+ dir: `./${name}`.fullname(dir)
127
+ }, this, this[name], cls);
128
+
129
+ this.manager[name] = manager;
130
+ return manager;
131
+ };
132
+
133
+ /**
134
+ * 初始化管理器集合
135
+ * @returns {Promise<void>} 初始化完成
136
+ */
137
+ GameWorld.prototype._initManager = async function () {
138
+ // 创建所有管理器实例
139
+ var component = this._createManager('component', '组件', Component);
140
+ var factory = this._createManager('factory', '工厂', Factory);
141
+ var logic = this._createManager('logic', '逻辑', Logic);
142
+ var system = this._createManager('system', '系统', System);
143
+ var scene = this._createManager('scene', '场景', Scene);
144
+
145
+ // 并行执行所有管理器的初始化操作
146
+ var initPromises = [
147
+ component.do('init'),
148
+ factory.do('init'),
149
+ logic.do('init'),
150
+ system.do('init'),
151
+ scene.do('init'),
152
+ ];
153
+
154
+ await Promise.all(initPromises);
155
+ // 创建实体管理器
156
+ this.entityAdmin = new EntityAdmin();
157
+ };
158
+
159
+ /**
160
+ * 初始化游戏循环
161
+ * @private
162
+ */
163
+ GameWorld.prototype._initGameLoop = async function () {
164
+ // 游戏循环
165
+ this._loop = new GameLoop(this.config.game_loop);
166
+ await this._loop.do('init', this, this.getEventer(), this.getLogger());
167
+ };
168
+
169
+ /**
170
+ * 加载资源
171
+ */
172
+ GameWorld.prototype._loadSources = async function () {
173
+ // 加载无需依赖关系,所以可以同时加载
174
+ await Promise.all([
175
+ this.manager.component.runAll('load'),
176
+ this.manager.factory.runAll('load'),
177
+ this.manager.logic.runAll('load'),
178
+ this.manager.system.runAll('load'),
179
+ this.manager.scene.runAll('load')
180
+ ]);
181
+ };
182
+
183
+ /**
184
+ * 初始化资源
185
+ */
186
+ GameWorld.prototype._initSources = async function () {
187
+ // 初始化顺序 scene -> system -> logic -> factory -> entity -> component ,需要依赖下级,所以自下而上初始化
188
+ await this.manager.component.runAll('init', this.getLogger());
189
+ await this.manager.factory.runAll('init', this.component, this.getEventer(), this.getLogger());
190
+ await this.entityAdmin.do('init', this.entities, this.factory, this.getEventer(), this.getLogger());
191
+ await this.manager.logic.runAll('init', this.getLogger());
192
+ await this.manager.system.runAll('init', this, this.getEventer(), this.getLogger());
193
+ await this.manager.scene.runAll('init', this.system, this.getEventer(), this.getLogger());
194
+ };
195
+
196
+ /**
197
+ * 初始化核心
198
+ * @param {object} channel 游戏频道
199
+ * @param {object} eventer 事件总线
200
+ * @param {object} logger 日志管理器
201
+ * @returns {void}
202
+ */
203
+ GameWorld.prototype._initCore = async function (channel, eventer, logger) {
204
+ // 初始化依赖项
205
+ if (logger) {
206
+ this.setLogger(logger);
207
+ }
208
+ if (eventer) {
209
+ this.getEventer = function () {
210
+ return eventer;
211
+ };
212
+ }
213
+ if (!channel) {
214
+ throw new Error('游戏世界必须绑定游戏频道');
215
+ }
216
+ else if (channel) {
217
+ this.getChannel = function () {
218
+ return channel;
219
+ };
220
+ }
221
+
222
+ // 初始化管理
223
+ await this._initManager();
224
+ // 加载资源
225
+ await this._loadSources();
226
+ // 初始化资源
227
+ await this._initSources();
228
+ // 初始化游戏循环
229
+ await this._initGameLoop();
230
+ };
231
+
232
+ /**
233
+ * 加载实体
234
+ * @returns {Promise<void>}
235
+ */
236
+ GameWorld.prototype._loadEntities = async function () {
237
+ try {
238
+ // 通过事件方式加载已存在的实体数据,避免直接操作数据库
239
+ var entities = await this.emitWait('entity_load', {
240
+ world_id: this.world_id,
241
+ world_name: this.config.name
242
+ });
243
+ if (entities && entities.length > 0) {
244
+ // 遍历实体列表,恢复实体对象
245
+ for (var i = 0; i < entities.length; i++) {
246
+ var info = entities[i];
247
+ // 使用工厂创建实体
248
+ var factory = this.createEntity(info.type, info.model);
249
+ if (factory) {
250
+ // 恢复玩家ID
251
+ if (info.player_id) {
252
+ this._player_ids.add(info.player_id);
253
+ }
254
+ }
255
+ }
256
+ }
257
+ } catch (error) {
258
+ this.log('error', `加载实体数据失败: `, error);
259
+ }
260
+ };
261
+
262
+ /**
263
+ * 启动资源
264
+ */
265
+ GameWorld.prototype._startSources = async function () {
266
+ // 并行启动游戏系统和场景
267
+ await Promise.all([
268
+ // 启动游戏系统
269
+ this.manager.system.runAll('start'),
270
+ // 启动游戏场景
271
+ this.manager.scene.runAll('start')
272
+ ]);
273
+ };
274
+
275
+ /**
276
+ * 启动核心
277
+ */
278
+ GameWorld.prototype._startCore = async function () {
279
+ // 加载实体(在启动前恢复已存在的实体)
280
+ await this._loadEntities();
281
+ // 启动资源
282
+ await this._startSources();
283
+ // 启动游戏循环
284
+ await this._loop.do('start');
285
+ };
286
+
287
+ /**
288
+ * 游戏世界更新
289
+ */
290
+ GameWorld.prototype.update = async function () {
291
+ await this.manager.system.runAll('update');
292
+ await this.manager.scene.runAll('update');
293
+ };
294
+
295
+ /**
296
+ * 保存脏数据实体
297
+ * @returns {Promise<void>}
298
+ */
299
+ GameWorld.prototype._saveDirtyEntities = async function () {
300
+ try {
301
+ var entities = [];
302
+ // 遍历所有实体,收集脏数据
303
+ for (var entity of this.entities.values()) {
304
+ if (entity.isDirty()) {
305
+ entities.push(entity);
306
+ // 触发实体数据变化事件
307
+ this.emitEvent('entity_changed', {
308
+ entity: entity,
309
+ world_id: this.world_id,
310
+ timestamp: Date.now()
311
+ });
312
+ }
313
+ }
314
+ if (entities.length > 0) {
315
+ // 通过事件方式保存脏数据实体
316
+ await this.emitWait('entity_save', {
317
+ world_id: this.world_id,
318
+ world_name: this.config.name,
319
+ entities: entities
320
+ });
321
+ // 重置脏标记
322
+ for (var i = 0; i < entities.length; i++) {
323
+ entities[i].isDirty(false);
324
+ }
325
+ this.log('debug', `保存脏数据实体 ${entities.length} 个`);
326
+ }
327
+ } catch (error) {
328
+ this.log('error', `保存脏数据实体失败: `, error);
329
+ }
330
+ };
331
+
332
+ /**
333
+ * 保存所有实体
334
+ * @returns {Promise<void>}
335
+ */
336
+ GameWorld.prototype._saveAllEntities = async function () {
337
+ try {
338
+ var all_entities = Array.from(this.entities.values());
339
+ if (all_entities.length > 0) {
340
+ // 通过事件方式保存所有实体
341
+ await this.emitWait('entity_save', {
342
+ world_id: this.world_id,
343
+ world_name: this.config.name,
344
+ entities: all_entities
345
+ });
346
+ this.log('info', `保存所有实体 ${all_entities.length} 个`);
347
+ }
348
+ } catch (error) {
349
+ this.log('error', `保存所有实体失败: `, error);
350
+ }
351
+ };
352
+
353
+ /**
354
+ * 销毁游戏世界
355
+ * @private
356
+ * @returns {Promise<void>} 销毁完成后的Promise
357
+ */
358
+ GameWorld.prototype._destroy = async function () {
359
+ // 销毁前保存所有实体
360
+ await this._saveAllEntities();
361
+ await this.manager.system.runAll('destroy');
362
+ await this.manager.scene.runAll('destroy');
363
+ };
364
+
365
+ /**
366
+ * 获取实体
367
+ * @param {object} id 实体ID
368
+ * @returns {object|null} 实体对象,如果不存在则返回null
369
+ */
370
+ GameWorld.prototype.getEntity = function (id) {
371
+ return this.entities.get(id);
372
+ };
373
+
374
+ /**
375
+ * 获取组件相关实体
376
+ * @param {Array} types 组件类型数组
377
+ * @returns {Array} 符合条件的实体数组
378
+ */
379
+ GameWorld.prototype.getEntitiesByTypes = function (types) {
380
+ // 实现实体查询逻辑
381
+ let result = [];
382
+ for (let entity of this.entities.values()) {
383
+ if (types.every(type => entity.hasComponent(type))) {
384
+ result.push(entity);
385
+ }
386
+ }
387
+ return result;
388
+ };
389
+
390
+ /**
391
+ * 获取相关标签实体
392
+ * @param {Array} tags 标签数组
393
+ * @returns {Array} 符合条件的实体数组
394
+ */
395
+ GameWorld.prototype.getEntitiesByTags = function (tags) {
396
+ // 实现实体查询逻辑
397
+ let result = [];
398
+ for (let entity of this.entities.values()) {
399
+ if (tags.every(type => entity.hasTag(type))) {
400
+ result.push(entity);
401
+ }
402
+ }
403
+ return result;
404
+ };
405
+
406
+ /**
407
+ * 创建实体
408
+ * @param {string} type 实体类型 - 可选值为 玩家、NPC、怪物、物品等
409
+ * @param {object} model 实体模型 - 可选,根据实体类型定义
410
+ * @returns {object} 创建的实体对象
411
+ */
412
+ GameWorld.prototype.createEntity = function (type = 'player', model = {}) {
413
+ // 使用工厂创建实体
414
+ var factory = this.factory[type];
415
+ if (!factory) {
416
+ throw new Error(`${this.config.title}游戏工厂(${type})不存在`);
417
+ }
418
+ let entity = factory.create(model);
419
+ this.entities.set(entity.entity_id, entity);
420
+
421
+ // 注册实体与玩家的映射关系
422
+ if (entity.player_id) {
423
+ // 尝试获取 Pusher 实例并注册映射
424
+ if ($.pusher) {
425
+ $.pusher.registerEntityPlayer(entity.entity_id, entity.player_id);
426
+ }
427
+ }
428
+
429
+ // 触发实体创建事件
430
+ this.emitEvent('entity_created', {
431
+ entity: entity,
432
+ world_id: this.world_id,
433
+ timestamp: Date.now()
434
+ });
435
+
436
+ return entity;
437
+ };
438
+
439
+ /**
440
+ * 玩家进入世界
441
+ * @param {string} player_id 玩家ID
442
+ * @param {string} entity_type 实体类型 - 可选值为 玩家、NPC、怪物、物品等
443
+ * @returns {object} 玩家实体对象
444
+ */
445
+ GameWorld.prototype.enter = async function (player_id, entity_type) {
446
+ // 参数校验
447
+ if (!player_id) {
448
+ throw new TypeError('玩家ID无效');
449
+ }
450
+ let player = this.getChannel().getPlayer(player_id);
451
+ // 参数校验
452
+ if (!player) {
453
+ throw new TypeError('玩家对象无效');
454
+ }
455
+ if (this._player_ids.has(player_id)) {
456
+ throw new Error(`玩家 ${player_id} 已存在`);
457
+ }
458
+
459
+ try {
460
+ this._addPlayer(player_id);
461
+ // 创建玩家实体
462
+ let entity = this.createEntity(entity_type || this.config.entity_type, player);
463
+
464
+ // 触发玩家进入世界事件
465
+ this.emitEvent('player_enter_world', {
466
+ world_id: this.world_id,
467
+ world_name: this.config.name,
468
+ player_id: player.player_id,
469
+ player_level: player.level,
470
+ timestamp: Date.now()
471
+ });
472
+
473
+ // 将玩家添加到默认场景
474
+ let default_scene = this.scene['default'];
475
+ if (default_scene) {
476
+ await default_scene.addPlayer(entity);
477
+ }
478
+ return entity;
479
+ } catch (error) {
480
+ this.log('error', `玩家进入世界失败: `, error);
481
+ throw error;
482
+ }
483
+ };
484
+
485
+ /**
486
+ * 玩家离开世界
487
+ * @param {string} player_id 玩家ID
488
+ * @returns {object} 离开的玩家实体
489
+ */
490
+ GameWorld.prototype.leave = async function (player_id) {
491
+ // 参数校验
492
+ if (!player_id) {
493
+ throw new TypeError('玩家ID无效');
494
+ }
495
+ // 查找玩家实体
496
+ let entity = this.entities.get(player_id);
497
+ if (!entity) {
498
+ throw new Error(`玩家 ${player_id} 不存在`);
499
+ }
500
+
501
+ // 从默认场景移除玩家
502
+ let default_scene = this.scene['default'];
503
+ if (default_scene) {
504
+ await default_scene.leave(entity);
505
+ }
506
+
507
+ // 触发玩家离开世界事件
508
+ this.emitEvent('player_leave_world', {
509
+ world_id: this.world_id,
510
+ world_name: this.config.name,
511
+ player_id: player_id,
512
+ timestamp: Date.now()
513
+ });
514
+
515
+ // 触发实体删除事件
516
+ this.emitEvent('entity_deleted', {
517
+ entity_id: entity.entity_id,
518
+ world_id: this.world_id,
519
+ timestamp: Date.now()
520
+ });
521
+
522
+ // 从实体管理器移除玩家实体
523
+ this.entities.delete(player_id);
524
+ // 从玩家ID集合中移除
525
+ this._removePlayer(player_id);
526
+ return entity;
527
+ };
528
+
529
+ /**
530
+ * 玩家进入场景
531
+ * @param {string} player_id 玩家ID
532
+ * @param {string} scene_id 场景ID
533
+ * @returns {boolean} 是否成功进入
534
+ */
535
+ GameWorld.prototype.enterScene = async function (player_id, scene_id) {
536
+ // 参数校验
537
+ if (!player_id) {
538
+ throw new TypeError('玩家ID无效');
539
+ }
540
+ if (!scene_id) {
541
+ throw new TypeError('场景ID无效');
542
+ }
543
+ // 查找玩家实体
544
+ let entity = this.entities.get(player_id);
545
+ if (!entity) {
546
+ throw new Error(`玩家 ${player_id} 不存在`);
547
+ }
548
+ // 查找场景
549
+ let scene = this.scene[scene_id];
550
+ if (!scene) {
551
+ throw new Error(`场景 ${scene_id} 不存在`);
552
+ }
553
+ // 触发玩家进入场景事件
554
+ this.emitEvent('player_enter_scene', {
555
+ world_id: this.world_id,
556
+ world_name: this.config.name,
557
+ player_id: player_id,
558
+ scene_id: scene_id,
559
+ timestamp: Date.now()
560
+ });
561
+
562
+ // 将玩家添加到场景
563
+ await scene.addPlayer(entity);
564
+ return true;
565
+ };
566
+
567
+ /**
568
+ * 添加玩家到世界
569
+ * @param {string} player_id 玩家ID
570
+ */
571
+ GameWorld.prototype._addPlayer = function (player_id) {
572
+ // 参数校验
573
+ if (!player_id) {
574
+ throw new TypeError('玩家ID无效');
575
+ }
576
+ // 检查玩家是否已存在
577
+ if (this._player_ids.has(player_id)) {
578
+ throw new Error(`玩家 ${player_id} 已存在`);
579
+ }
580
+ // 添加玩家ID到集合
581
+ this._player_ids.add(player_id);
582
+ };
583
+
584
+ /**
585
+ * 移除玩家
586
+ * @param {string} player_id 玩家ID
587
+ * @returns {boolean} 是否成功移除
588
+ */
589
+ GameWorld.prototype._removePlayer = function (player_id) {
590
+ // 参数校验
591
+ if (!player_id) {
592
+ throw new TypeError('玩家ID无效');
593
+ }
594
+ return this._player_ids.delete(player_id);
595
+ };
596
+
597
+ /**
598
+ * 获取世界玩家数量
599
+ * @returns {number} 玩家数量
600
+ */
601
+ GameWorld.prototype.getPlayerNum = function () {
602
+ return this._player_ids.size;
603
+ };
604
+
605
+ /**
606
+ * 检查玩家是否在世界中
607
+ * @param {string} player_id 玩家ID
608
+ * @returns {boolean} 是否存在
609
+ */
610
+ GameWorld.prototype.hasPlayer = function (player_id) {
611
+ return this._player_ids.has(player_id);
612
+ };
613
+
614
+ /**
615
+ * 获取所有玩家ID
616
+ * @returns {Array} 玩家ID数组
617
+ */
618
+ GameWorld.prototype.getAllPlayerIds = function () {
619
+ return Array.from(this._player_ids);
620
+ };
621
+
622
+ exports.GameWorld = GameWorld;
@@ -0,0 +1,16 @@
1
+ {
2
+ // 游戏名称
3
+ "name": "${name || 'world'}",
4
+ // 游戏标题
5
+ "title": "${title || '游戏'}",
6
+ // 游戏描述
7
+ "description": "${description || '这是一个游戏'}",
8
+ // 游戏主脚本 - 可自定义游戏初始化,一般情况不需要定义
9
+ "main": "${main || 'index.js'}",
10
+ // 游戏状态 - 1 正常 0 禁用
11
+ "state": 1,
12
+ // 游戏排序 - 数字越小越靠前
13
+ "sort": 100,
14
+ // 游戏类型 - 角色扮演rpg、卡牌游戏card、策略游戏strategy、模拟经营simulation
15
+ "type": "${type || 'card'}"
16
+ }