mm_os 3.3.0 → 4.0.0

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 +491 -99
  3. package/README_EN.md +498 -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/com/event/com.json +5 -0
  28. package/{core/com → com}/event/config.tpl.json +8 -8
  29. package/com/event/drive.js +59 -0
  30. package/com/event/index.js +409 -0
  31. package/com/event/script.tpl.js +23 -0
  32. package/com/mqtt/com.json +5 -0
  33. package/{core/com → com}/mqtt/config.tpl.json +3 -5
  34. package/com/mqtt/drive.js +676 -0
  35. package/com/mqtt/index.js +822 -0
  36. package/com/mqtt/mm_mqtt.js +425 -0
  37. package/com/mqtt/script.tpl.js +723 -0
  38. package/com/nav/com.json +5 -0
  39. package/com/nav/config.tpl.json +84 -0
  40. package/com/nav/drive.js +702 -0
  41. package/com/nav/index.js +231 -0
  42. package/{core/com → com}/nav/tpl/admin_pc/page_config.vue +280 -280
  43. package/{core/com → com}/nav/tpl/admin_pc/page_config_form.vue +194 -194
  44. package/com/nav/tpl/admin_pc/page_form.vue +180 -0
  45. package/com/nav/tpl/admin_pc/page_view.vue +124 -0
  46. package/com/nav/tpl/dev_pc/page_default.vue +247 -0
  47. package/com/nav/tpl/dev_pc/page_type.vue +313 -0
  48. package/com/nav/tpl/home_pc/page_default.vue +234 -0
  49. package/com/nav/tpl/home_pc/page_form.vue +137 -0
  50. package/com/nav/tpl/home_pc/page_list.vue +234 -0
  51. package/com/nav/tpl/home_pc/page_nav.vue +221 -0
  52. package/com/nav/tpl/home_pc/page_type.vue +234 -0
  53. package/com/nav/tpl/home_pc/page_view.vue +125 -0
  54. package/com/nav/tpl/home_phone/page_channel.vue +234 -0
  55. package/com/nav/tpl/home_phone/page_default.vue +234 -0
  56. package/com/nav/tpl/home_phone/page_form.vue +137 -0
  57. package/com/nav/tpl/home_phone/page_nav.vue +237 -0
  58. package/com/nav/tpl/home_phone/page_type.vue +234 -0
  59. package/com/nav/tpl/home_phone/page_view.vue +125 -0
  60. package/com/nav/viewmodel.js +446 -0
  61. package/com/param/com.json +5 -0
  62. package/{core/com → com}/param/config.tpl.json +7 -1
  63. package/com/param/drive.js +502 -0
  64. package/com/param/index.js +155 -0
  65. package/com/param/script.tpl.js +12 -0
  66. package/com/pendant/com.json +5 -0
  67. package/{core/com/component → com/pendant}/config.tpl.json +15 -13
  68. package/com/pendant/drive.js +204 -0
  69. package/com/pendant/index.js +441 -0
  70. package/com/pendant/pendant.html +16 -0
  71. package/com/pendant/script.tpl.js +18 -0
  72. package/com/socket/com.json +5 -0
  73. package/com/socket/config.tpl.json +12 -0
  74. package/com/socket/drive.js +651 -0
  75. package/com/socket/index.js +351 -0
  76. package/com/socket/script.tpl.js +41 -0
  77. package/com/sql/com.json +5 -0
  78. package/{core/com → com}/sql/config.tpl.json +13 -9
  79. package/com/sql/drive.js +1259 -0
  80. package/com/sql/index.js +150 -0
  81. package/com/sql/script.tpl.js +47 -0
  82. package/com/static/com.json +5 -0
  83. package/{core/com → com}/static/config.tpl.json +10 -6
  84. package/com/static/drive.js +194 -0
  85. package/com/static/index.js +226 -0
  86. package/com/static/script.tpl.js +28 -0
  87. package/com/task/com.json +5 -0
  88. package/{core/com → com}/task/config.tpl.json +4 -6
  89. package/com/task/drive.js +405 -0
  90. package/com/task/index.js +148 -0
  91. package/com/task/script.tpl.js +37 -0
  92. package/com/template/com.json +5 -0
  93. package/com/template/config.tpl.json +16 -0
  94. package/com/template/drive.js +80 -0
  95. package/com/template/index.js +141 -0
  96. package/com.js +156 -0
  97. package/common/README.md +2 -0
  98. package/common/handler/msg/handler.json +22 -0
  99. package/common/handler/msg/index.js +23 -0
  100. package/common/handler/player/handler.json +22 -0
  101. package/common/handler/player/index.js +287 -0
  102. package/common/handler/user/handler.json +22 -0
  103. package/common/handler/user/index.js +23 -0
  104. package/common/middleware/web_after/index.js +29 -0
  105. package/common/middleware/web_after/middleware.json +9 -0
  106. package/common/middleware/web_base/index.js +113 -0
  107. package/common/middleware/web_base/middleware.json +19 -0
  108. package/common/middleware/web_before/index.js +33 -0
  109. package/common/middleware/web_before/middleware.json +9 -0
  110. package/common/middleware/web_cors/index.js +87 -0
  111. package/common/middleware/web_cors/middleware.json +24 -0
  112. package/common/middleware/web_error/index.js +119 -0
  113. package/common/middleware/web_error/middleware.json +18 -0
  114. package/common/middleware/web_ip/index.js +15 -0
  115. package/common/middleware/web_ip/middleware.json +14 -0
  116. package/common/middleware/web_logger/index.js +156 -0
  117. package/common/middleware/web_logger/middleware.json +14 -0
  118. package/common/middleware/web_main/index.js +24 -0
  119. package/common/middleware/web_main/middleware.json +9 -0
  120. package/common/middleware/web_static/index.js +73 -0
  121. package/common/middleware/web_static/middleware.json +54 -0
  122. package/common/middleware/web_waf/index.js +385 -0
  123. package/common/middleware/web_waf/middleware.json +13 -0
  124. package/common/model/msg/index.js +88 -0
  125. package/common/model/msg/model.json +401 -0
  126. package/common/model/player/index.js +63 -0
  127. package/common/model/player/model.json +185 -0
  128. package/common/model/user/index.js +11 -0
  129. package/common/model/user/model.json +219 -0
  130. package/core/app/config.tpl.json +67 -0
  131. package/core/app/index.js +632 -0
  132. package/core/app/script.tpl.js +52 -0
  133. package/core/channel/index.js +899 -0
  134. package/core/channel/matcher.js +585 -0
  135. package/core/com/config.tpl.json +16 -0
  136. package/core/com/index.js +74 -0
  137. package/core/com/script.tpl.js +5 -0
  138. package/core/component/component.js +42 -0
  139. package/core/component/config.tpl.json +63 -0
  140. package/core/component/index.js +273 -0
  141. package/core/component/script.tpl.js +19 -0
  142. package/core/controller/config.tpl.json +14 -0
  143. package/core/controller/index.js +373 -0
  144. package/core/controller/script.tpl.js +27 -0
  145. package/core/factory/config.tpl.json +14 -0
  146. package/core/factory/entity.js +275 -0
  147. package/core/factory/index.js +241 -0
  148. package/core/factory/script.tpl.js +16 -0
  149. package/core/game/bat/index.js +137 -0
  150. package/core/game/bat/world.js +622 -0
  151. package/core/game/config.tpl.json +16 -0
  152. package/core/game/entity_admin.js +230 -0
  153. package/core/game/index.js +186 -0
  154. package/core/handler/config.tpl.json +22 -0
  155. package/core/handler/index.js +181 -0
  156. package/core/handler/script.tpl.js +23 -0
  157. package/core/logic/config.tpl.json +14 -0
  158. package/core/logic/index.js +59 -0
  159. package/core/logic/script.tpl.js +19 -0
  160. package/core/middleware/config.tpl.json +16 -0
  161. package/core/middleware/index.js +125 -0
  162. package/core/middleware/script.tpl.js +37 -0
  163. package/core/mod/config.tpl.json +22 -0
  164. package/core/mod/index.js +130 -0
  165. package/core/mod/script.tpl.js +34 -0
  166. package/core/model/config.tpl.json +219 -0
  167. package/core/model/index.js +272 -0
  168. package/core/model/model.js +27 -0
  169. package/core/model/script.tpl.js +20 -0
  170. package/core/notifier/config.tpl.json +14 -0
  171. package/core/notifier/index.js +77 -0
  172. package/core/notifier/script.tpl.js +20 -0
  173. package/core/plugin/config.tpl.json +24 -0
  174. package/core/plugin/index.js +232 -0
  175. package/core/plugin/script.tpl.js +51 -0
  176. package/core/pusher/config.tpl.json +14 -0
  177. package/core/pusher/index.js +161 -0
  178. package/core/pusher/script.tpl.js +20 -0
  179. package/core/room/bat/index.js +170 -0
  180. package/core/room/bat/room.js +524 -0
  181. package/core/room/config.tpl.json +20 -0
  182. package/core/room/index.js +249 -0
  183. package/core/room/room.js +61 -0
  184. package/core/scene/config.tpl.json +14 -0
  185. package/core/scene/index.js +466 -0
  186. package/core/scene/loop.js +1255 -0
  187. package/core/scene/map.js +28 -0
  188. package/core/scene/script.tpl.js +22 -0
  189. package/core/sender/config.tpl.json +14 -0
  190. package/core/sender/index.js +79 -0
  191. package/core/sender/script.tpl.js +20 -0
  192. package/core/service/config.tpl.json +14 -0
  193. package/core/service/index.js +100 -0
  194. package/core/service/script.tpl.js +25 -0
  195. package/core/store/config.tpl.json +26 -0
  196. package/core/store/index.js +1755 -0
  197. package/core/store/script.tpl.js +22 -0
  198. package/core/store/sql.js +1464 -0
  199. package/core/system/config.tpl.json +18 -0
  200. package/core/system/index.js +312 -0
  201. package/core/system/script.tpl.js +77 -0
  202. package/core/view/config.tpl.json +14 -0
  203. package/core/view/index.js +91 -0
  204. package/core/view/script.tpl.js +20 -0
  205. package/core/zone/bat/index.js +725 -0
  206. package/core/zone/config.tpl.json +54 -0
  207. package/core/zone/index.js +614 -0
  208. package/core/zone/script.tpl.js +10 -0
  209. package/core/zone/zone_bat.js +136 -0
  210. package/core//345/237/272/347/261/273/346/250/241/345/235/227/346/270/205/345/215/225.md +24 -0
  211. package/index.js +17 -314
  212. package/os.js +57 -0
  213. package/package.json +60 -58
  214. package/server.js +598 -0
  215. package/README.en.md +0 -36
  216. package/conf.json +0 -3
  217. package/core/base/mqtt/index.js +0 -1107
  218. package/core/base/mqtt/lib.js +0 -40
  219. package/core/base/web/index.js +0 -243
  220. package/core/com/api/com.json +0 -4
  221. package/core/com/api/drive.js +0 -668
  222. package/core/com/api/index.js +0 -108
  223. package/core/com/api/oauth.js +0 -158
  224. package/core/com/api/script.js +0 -32
  225. package/core/com/app/README.md +0 -3
  226. package/core/com/app/com.json +0 -4
  227. package/core/com/app/config.tpl.json +0 -16
  228. package/core/com/app/drive.js +0 -309
  229. package/core/com/app/index.js +0 -211
  230. package/core/com/app/script.js +0 -155
  231. package/core/com/cmd/com.json +0 -4
  232. package/core/com/cmd/config.tpl.json +0 -66
  233. package/core/com/cmd/drive.js +0 -513
  234. package/core/com/cmd/index.js +0 -354
  235. package/core/com/cmd/old/5w2h.js +0 -54
  236. package/core/com/cmd/old/drive.js +0 -423
  237. package/core/com/cmd/script.js +0 -11
  238. package/core/com/component/README.md +0 -3
  239. package/core/com/component/com.json +0 -4
  240. package/core/com/component/component.html +0 -16
  241. package/core/com/component/drive.js +0 -197
  242. package/core/com/component/index.js +0 -312
  243. package/core/com/component/script.js +0 -18
  244. package/core/com/db/com.json +0 -4
  245. package/core/com/db/drive.js +0 -1160
  246. package/core/com/db/index.js +0 -176
  247. package/core/com/event/com.json +0 -4
  248. package/core/com/event/drive.js +0 -133
  249. package/core/com/event/index.js +0 -345
  250. package/core/com/event/script.js +0 -26
  251. package/core/com/eventer/com.js +0 -477
  252. package/core/com/eventer/com.json +0 -4
  253. package/core/com/middleware/com.js +0 -153
  254. package/core/com/middleware/com.json +0 -4
  255. package/core/com/middleware/config.tpl.json +0 -8
  256. package/core/com/middleware/script.js +0 -9
  257. package/core/com/mqtt/com.json +0 -4
  258. package/core/com/mqtt/drive.js +0 -600
  259. package/core/com/mqtt/index.js +0 -572
  260. package/core/com/mqtt/mm_mqtt.js +0 -330
  261. package/core/com/mqtt/script.js +0 -604
  262. package/core/com/msg/com.js +0 -296
  263. package/core/com/msg/com.json +0 -4
  264. package/core/com/nav/com.json +0 -4
  265. package/core/com/nav/config.tpl.json +0 -75
  266. package/core/com/nav/drive.js +0 -549
  267. package/core/com/nav/index.js +0 -182
  268. package/core/com/nav/tpl/admin_pc/page_form.vue +0 -180
  269. package/core/com/nav/tpl/admin_pc/page_view.vue +0 -124
  270. package/core/com/nav/tpl/dev_pc/page_default.vue +0 -247
  271. package/core/com/nav/tpl/dev_pc/page_type.vue +0 -313
  272. package/core/com/nav/tpl/home_pc/page_default.vue +0 -234
  273. package/core/com/nav/tpl/home_pc/page_form.vue +0 -137
  274. package/core/com/nav/tpl/home_pc/page_list.vue +0 -234
  275. package/core/com/nav/tpl/home_pc/page_nav.vue +0 -221
  276. package/core/com/nav/tpl/home_pc/page_type.vue +0 -234
  277. package/core/com/nav/tpl/home_pc/page_view.vue +0 -125
  278. package/core/com/nav/tpl/home_phone/page_channel.vue +0 -234
  279. package/core/com/nav/tpl/home_phone/page_default.vue +0 -234
  280. package/core/com/nav/tpl/home_phone/page_form.vue +0 -137
  281. package/core/com/nav/tpl/home_phone/page_nav.vue +0 -237
  282. package/core/com/nav/tpl/home_phone/page_type.vue +0 -234
  283. package/core/com/nav/tpl/home_phone/page_view.vue +0 -125
  284. package/core/com/nav/viewmodel.js +0 -296
  285. package/core/com/param/drive.js +0 -366
  286. package/core/com/param/index.js +0 -80
  287. package/core/com/param/script.js +0 -12
  288. package/core/com/param/test.js +0 -98
  289. package/core/com/plugin/README.md +0 -3
  290. package/core/com/plugin/com.json +0 -4
  291. package/core/com/plugin/config.tpl.json +0 -26
  292. package/core/com/plugin/drive.js +0 -536
  293. package/core/com/plugin/index.js +0 -259
  294. package/core/com/plugin/script.js +0 -213
  295. package/core/com/rpc/com.json +0 -4
  296. package/core/com/rpc/drive.js +0 -160
  297. package/core/com/rpc/index.js +0 -87
  298. package/core/com/rpc/rpc.js +0 -118
  299. package/core/com/socket/com.json +0 -4
  300. package/core/com/socket/config.tpl.json +0 -14
  301. package/core/com/socket/drive.js +0 -403
  302. package/core/com/socket/index.js +0 -62
  303. package/core/com/socket/script.js +0 -42
  304. package/core/com/sql/drive.js +0 -1087
  305. package/core/com/sql/index.js +0 -83
  306. package/core/com/sql/script.js +0 -48
  307. package/core/com/static/com.json +0 -4
  308. package/core/com/static/drive.js +0 -220
  309. package/core/com/static/index.js +0 -149
  310. package/core/com/static/script.js +0 -28
  311. package/core/com/task/com.json +0 -4
  312. package/core/com/task/drive.js +0 -403
  313. package/core/com/task/index.js +0 -110
  314. package/core/com/task/script.js +0 -37
  315. package/core/com/timer/com.js +0 -217
  316. package/core/com/timer/com.json +0 -4
  317. package/core/com/tpl/com.js +0 -19
  318. package/core/com/tpl/com.json +0 -4
  319. package/lib/actions.js +0 -50
  320. package/lib/base.js +0 -361
  321. package/lib/com.js +0 -29
  322. package/lib/ref.js +0 -121
  323. package/middleware/mqtt_base/index.js +0 -10
  324. package/middleware/mqtt_base/middleware.json +0 -10
  325. package/middleware/performance/index.js +0 -151
  326. package/middleware/performance/middleware.json +0 -16
  327. package/middleware/security_audit/index.js +0 -549
  328. package/middleware/security_audit/middleware.json +0 -48
  329. package/middleware/security_headers/index.js +0 -487
  330. package/middleware/security_headers/middleware.json +0 -45
  331. package/middleware/waf/index.js +0 -348
  332. package/middleware/waf/middleware.json +0 -10
  333. package/middleware/waf_ddos/index.js +0 -520
  334. package/middleware/waf_ddos/middleware.json +0 -38
  335. package/middleware/waf_ip/index.js +0 -379
  336. package/middleware/waf_ip/middleware.json +0 -49
  337. package/middleware/waf_xss/index.js +0 -269
  338. package/middleware/waf_xss/middleware.json +0 -18
  339. package/middleware/web_after/index.js +0 -33
  340. package/middleware/web_after/middleware.json +0 -9
  341. package/middleware/web_base/index.js +0 -90
  342. package/middleware/web_base/middleware.json +0 -9
  343. package/middleware/web_before/index.js +0 -27
  344. package/middleware/web_before/middleware.json +0 -9
  345. package/middleware/web_check/index.js +0 -28
  346. package/middleware/web_check/middleware.json +0 -9
  347. package/middleware/web_main/index.js +0 -28
  348. package/middleware/web_main/middleware.json +0 -9
  349. package/middleware/web_proxy/index.js +0 -37
  350. package/middleware/web_proxy/middleware.json +0 -9
  351. package/middleware/web_render/index.js +0 -87
  352. package/middleware/web_render/middleware.json +0 -9
  353. package/middleware/web_socket/index.js +0 -34
  354. package/middleware/web_socket/middleware.json +0 -9
  355. package/middleware/web_static/index.js +0 -115
  356. package/middleware/web_static/middleware.json +0 -9
  357. /package/{core/com → com}/api/README.md +0 -0
  358. /package/{core/com → com}/db/README.md +0 -0
  359. /package/{core/com → com}/event/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,899 @@
1
+ const {
2
+ Drive,
3
+ Manager
4
+ } = require('mm_machine');
5
+ const {
6
+ RoomAdmin
7
+ } = require('../room/index.js');
8
+ const {
9
+ Matcher
10
+ } = require('./matcher.js');
11
+
12
+ /**
13
+ * 游戏频道 - 平行世界管理器
14
+ * 负责管理频道的创建、销毁、玩家隔离和频道间通信
15
+ */
16
+ class Channel extends Drive {
17
+ static config = {
18
+ 'name': 'default',
19
+ 'title': '默认频道',
20
+ 'min_level': 0,
21
+ 'max_level': 1000,
22
+ 'max_players': 5000,
23
+ 'type': 'normal',
24
+ 'load_threshold': 0.8,
25
+ 'main': '',
26
+ 'match': {
27
+ 'wait_time': 120000,
28
+ 'lv_range_init': 5,
29
+ 'lv_range_max': 20,
30
+ 'lv_expand_int': 10000,
31
+ 'interval': 1000
32
+ }
33
+ };
34
+
35
+ /**
36
+ * 构造函数
37
+ * @param {object} config 配置参数
38
+ */
39
+ constructor(config) {
40
+ super({ ...Channel.config, ...config });
41
+
42
+ // 游戏世界集合
43
+ this.worlds = new Map();
44
+ }
45
+ }
46
+
47
+ /**
48
+ * 预置
49
+ */
50
+ Channel.prototype._preset = function () {
51
+ this.channel_id = 0;
52
+ this.status = 1;
53
+ this.stats = {
54
+ player: 0,
55
+ room: 0,
56
+ world: 0,
57
+ message: 0,
58
+ last_update: Date.now()
59
+ };
60
+
61
+ this._monitorTimer = null;
62
+
63
+ this.roomAdmin = null;
64
+ this.matcher = null;
65
+
66
+ // 主世界ID
67
+ this._main_world_id = '';
68
+ };
69
+
70
+ /**
71
+ * 获取模板目录
72
+ * @returns {string} 模板目录
73
+ */
74
+ Channel.prototype.getTplDir = function () {
75
+ return __dirname;
76
+ };
77
+
78
+ /**
79
+ * 初始化核心
80
+ * @param {object} zone 分区对象
81
+ * @param {object} eventer 事件管理器
82
+ * @param {object} logger 日志管理器
83
+ */
84
+ Channel.prototype._initCore = async function (zone, eventer, logger) {
85
+ if (!zone) {
86
+ throw new TypeError('分区对象不能为空');
87
+ }
88
+ else {
89
+ this.getZone = function () {
90
+ return zone;
91
+ };
92
+ }
93
+
94
+ if (logger) {
95
+ this.setLogger(logger);
96
+ }
97
+ if (eventer) {
98
+ this.getEventer = function () {
99
+ return eventer;
100
+ };
101
+ }
102
+
103
+ await this._initManager();
104
+ await this._loadSources();
105
+ await this._initSources();
106
+
107
+ await this._loadWorlds();
108
+
109
+ await this._initRoomAdmin();
110
+
111
+ await this._loadRooms();
112
+
113
+ await this._initMatcher();
114
+ };
115
+
116
+ /**
117
+ * 加载世界
118
+ * @returns {Promise<void>}
119
+ */
120
+ Channel.prototype._loadWorlds = async function () {
121
+ // 通过事件方式加载已创建的世界数据,避免直接操作数据库
122
+ var worlds = await this.emitWait('world_load', {
123
+ zone_name: this.getZone().config.name,
124
+ channel_id: this.channel_id
125
+ });
126
+ if (worlds && worlds.length > 0) {
127
+ // 遍历世界列表,创建世界对象
128
+ for (var i = 0; i < worlds.length; i++) {
129
+ var info = worlds[i];
130
+ await this.createWorld(info, info.world_id);
131
+ }
132
+ this.log('info', `加载世界成功,共 ${worlds.length} 个`);
133
+ }
134
+
135
+ // 加载所有游戏世界
136
+ var promises = [];
137
+ for (var o of this.worlds.values()) {
138
+ promises.push(o.do('load'));
139
+ }
140
+ await Promise.all(promises);
141
+ };
142
+
143
+ /**
144
+ * 初始化房间管理器
145
+ */
146
+ Channel.prototype._initRoomAdmin = async function () {
147
+ this.roomAdmin = new RoomAdmin();
148
+ await this.roomAdmin.do('init', this);
149
+ };
150
+
151
+ /**
152
+ * 初始化匹配器
153
+ */
154
+ Channel.prototype._initMatcher = async function () {
155
+ this.matcher = new Matcher(this.config.match, this);
156
+ await this.matcher.do('init', this);
157
+ };
158
+
159
+ /**
160
+ * 初始化管理器
161
+ */
162
+ Channel.prototype._initManager = async function () {
163
+ // var dir = this._getDir().dirname().dirname();
164
+ // var game = new Manager({
165
+ // name: 'game',
166
+ // title: '游戏',
167
+ // filename: 'game.json',
168
+ // tpl_dir: `../game/`.fullname(__dirname),
169
+ // base_dir: '',
170
+ // // base_dir: `../../common/${name}/`.fullname(__dirname),
171
+ // dir: `./game`.fullname(dir)
172
+ // }, this, this.game, Game);
173
+ // await game.do('init');
174
+ // this.manager.game = game;
175
+ };
176
+
177
+ /**
178
+ * 获取游戏管理器目录
179
+ * @returns {string} 游戏管理器目录
180
+ */
181
+ Channel.prototype._getDir = function () {
182
+ return this.getZone()._getDir();
183
+ };
184
+
185
+ /**
186
+ * 加载资源
187
+ */
188
+ Channel.prototype._loadSources = async function () {
189
+ await this.manager.game.runAll('load');
190
+ };
191
+
192
+ /**
193
+ * 设置主世界ID
194
+ * @param {string} world_id 主世界ID
195
+ */
196
+ Channel.prototype.setMainWorld = function (world_id) {
197
+ this._main_world_id = world_id;
198
+ };
199
+
200
+ /**
201
+ * 初始化资源
202
+ */
203
+ Channel.prototype._initSources = async function () {
204
+ await this.manager.game.runAll('init', this, this.getEventer(), this.getLogger());
205
+ };
206
+
207
+ /**
208
+ * 加载游戏房间
209
+ * @returns {Promise<void>}
210
+ */
211
+ Channel.prototype._loadRooms = async function () {
212
+ // 通过事件方式加载已创建的房间数据,避免直接操作数据库
213
+ var rooms = await this.emitWait('room_load', {
214
+ zone_name: this.getZone().config.name,
215
+ channel_id: this.channel_id
216
+ });
217
+ if (rooms && rooms.length > 0) {
218
+ // 遍历房间列表,创建房间对象
219
+ for (var i = 0; i < rooms.length; i++) {
220
+ var info = rooms[i];
221
+ var room = await this.roomAdmin.create(info, info.owner);
222
+ // 恢复房间原有ID
223
+ if (info.room_id) {
224
+ this.roomAdmin._rooms.delete(room.room_id);
225
+ room.room_id = info.room_id;
226
+ this.roomAdmin._rooms.set(room.room_id, room);
227
+ }
228
+ // 恢复房间状态
229
+ if (info.state) {
230
+ room.state = info.state;
231
+ }
232
+ }
233
+ this.log('info', `加载房间成功,共 ${rooms.length} 个`);
234
+ }
235
+
236
+ // 加载所有游戏房间
237
+ var promises = [];
238
+ for (var o of this.rooms.values()) {
239
+ promises.push(o.do('load'));
240
+ }
241
+ await Promise.all(promises);
242
+ };
243
+
244
+ /**
245
+ * 启动核心
246
+ */
247
+ Channel.prototype._startCore = async function () {
248
+ await this.manager.game.runAll('start');
249
+ await this.matcher.do('start');
250
+ this._startMonitor();
251
+ await this._startWorlds();
252
+ };
253
+
254
+ /**
255
+ * 启动游戏世界
256
+ */
257
+ Channel.prototype._startWorlds = async function () {
258
+ var promises = [];
259
+ for (let o of this.worlds.values()) {
260
+ promises.push(o.do('start'));
261
+ }
262
+ await Promise.all(promises);
263
+ };
264
+
265
+ /**
266
+ * 初始化默认房间
267
+ */
268
+ Channel.prototype._initRooms = async function () {
269
+ var promises = [];
270
+ for (let o of this.rooms.values()) {
271
+ promises.push(o.do('init', this, this.getEventer(), this.getLogger()));
272
+ }
273
+ await Promise.all(promises);
274
+ };
275
+
276
+ /**
277
+ * 启动频道监控
278
+ */
279
+ Channel.prototype._startMonitor = function () {
280
+ this._monitorTimer = setInterval(() => {
281
+ this._updateStatus();
282
+ }, 30000);
283
+ };
284
+
285
+ /**
286
+ * 更新频道状态
287
+ */
288
+ Channel.prototype._updateStatus = function () {
289
+ var player = this.player_ids.size;
290
+ var max_players = this.config.max_players;
291
+ var load_ratio = player / max_players;
292
+
293
+ if (load_ratio >= 1) {
294
+ this.status = 3;
295
+ } else if (load_ratio >= this.config.load_threshold) {
296
+ this.status = 2;
297
+ } else {
298
+ this.status = 1;
299
+ }
300
+
301
+ this.stats.player = player;
302
+ this.stats.room = this.rooms.size;
303
+ this.stats.world = this.worlds.size;
304
+ this.stats.last_update = Date.now();
305
+ };
306
+
307
+ /**
308
+ * 玩家进入频道
309
+ * @param {string} player_id 玩家ID
310
+ * @returns {object} 世界对象
311
+ */
312
+ Channel.prototype.enter = function (player_id) {
313
+ if (!player_id) {
314
+ throw new TypeError('玩家ID不能为空');
315
+ }
316
+
317
+ if (this.player_ids.has(player_id)) {
318
+ throw new Error('玩家已在当前频道中');
319
+ }
320
+
321
+ var player = this.getZone().getPlayer(player_id);
322
+ if (!player) {
323
+ throw new Error(`玩家 ${player_id} 不存在`);
324
+ }
325
+
326
+ var {
327
+ min_level,
328
+ max_level,
329
+ status,
330
+ max_players
331
+ } = this.config;
332
+
333
+ this._validateStatus(status);
334
+ this._validateQualify(player, min_level, max_level, max_players);
335
+
336
+ try {
337
+ this.player_ids.set(player_id, true);
338
+
339
+ this.emitEvent('player_enter_channel', {
340
+ channel_id: this.config.name,
341
+ player_id: player_id,
342
+ player_level: player.level,
343
+ timestamp: Date.now()
344
+ });
345
+
346
+ let world = this.enterMainWorld(player_id);
347
+ return world;
348
+ } catch (error) {
349
+ this.player_ids.delete(player_id);
350
+ throw error;
351
+ }
352
+ };
353
+
354
+ /**
355
+ * 验证频道状态
356
+ * @param {number} status 频道状态
357
+ */
358
+ Channel.prototype._validateStatus = function (status) {
359
+ if (status === 0) {
360
+ throw new Error('频道已关闭,无法进入');
361
+ }
362
+ if (status === 2) {
363
+ throw new Error('频道维护中,暂时无法进入');
364
+ }
365
+ if (status === 3) {
366
+ throw new Error('频道爆满,请稍后再试');
367
+ }
368
+ };
369
+
370
+ /**
371
+ * 检查玩家是否在频道中
372
+ * @param {string} player_id 玩家ID
373
+ * @returns {boolean} 是否在频道中
374
+ */
375
+ Channel.prototype._hasPlayer = function (player_id) {
376
+ return this.player_ids.has(player_id);
377
+ };
378
+
379
+ /**
380
+ * 验证玩家资格
381
+ * @param {object} player 玩家对象
382
+ * @param {number} min_level 最低等级
383
+ * @param {number} max_level 最高等级
384
+ * @param {number} max_players 最大玩家数
385
+ */
386
+ Channel.prototype._validateQualify = function (player, min_level, max_level, max_players) {
387
+ if (player.level < min_level || player.level > max_level) {
388
+ var msg = `境界不符,无法进入此频道(要求等级:${min_level}-${max_level})`;
389
+ throw new Error(msg);
390
+ }
391
+
392
+ if (this.player_ids.size >= max_players) {
393
+ throw new Error('频道人数已达上限,无法进入');
394
+ }
395
+
396
+ if (this._hasPlayer(player.player_id)) {
397
+ throw new Error('玩家已在当前频道中');
398
+ }
399
+ };
400
+
401
+ /**
402
+ * 获取默认房间
403
+ * @param {string} player_id 玩家ID
404
+ * @returns {object} 房间对象
405
+ */
406
+ Channel.prototype.getDefaultRoom = async function (player_id) {
407
+ var player = this.getPlayer(player_id);
408
+
409
+ var room_name = player.returning ? 'main_room' : 'cultivation_area';
410
+ var room = this.rooms.get(room_name);
411
+
412
+ if (!room) {
413
+ throw new Error(`默认房间 ${room_name} 不存在`);
414
+ }
415
+
416
+ return room;
417
+ };
418
+
419
+ /**
420
+ * 玩家退出频道
421
+ * @param {string} player_id 玩家ID
422
+ * @returns {boolean} 是否成功退出
423
+ */
424
+ Channel.prototype.leave = async function (player_id) {
425
+ if (!player_id) {
426
+ throw new TypeError('玩家ID不能为空');
427
+ }
428
+
429
+ if (!this.player_ids.has(player_id)) {
430
+ throw new Error('玩家不在当前频道中');
431
+ }
432
+
433
+ this.player_ids.delete(player_id);
434
+
435
+ this.emitEvent('player_leave_channel', {
436
+ channel_id: this.config.name,
437
+ player_id: player_id,
438
+ timestamp: Date.now()
439
+ });
440
+ return true;
441
+ };
442
+
443
+ /**
444
+ * 强制踢出玩家
445
+ * @param {string} player_id 玩家ID
446
+ * @param {string} reason 踢出原因
447
+ * @returns {boolean} 是否成功踢出
448
+ */
449
+ Channel.prototype.kickPlayer = async function (player_id, reason = '系统维护') {
450
+ if (!player_id) {
451
+ throw new TypeError('玩家ID不能为空');
452
+ }
453
+
454
+ if (!this.player_ids.has(player_id)) {
455
+ throw new Error('玩家不在当前频道中');
456
+ }
457
+
458
+ this.player_ids.delete(player_id);
459
+
460
+ this.emitEvent('player_kicked_channel', {
461
+ channel_id: this.config.name,
462
+ player_id: player_id,
463
+ reason: reason,
464
+ timestamp: Date.now()
465
+ });
466
+ return true;
467
+ };
468
+
469
+ /**
470
+ * 获取玩家对象
471
+ * @param {string} player_id 玩家ID
472
+ * @returns {object} 玩家对象
473
+ */
474
+ Channel.prototype.getPlayer = function (player_id) {
475
+ if (!player_id) {
476
+ throw new TypeError('玩家ID不能为空');
477
+ }
478
+
479
+ return this.getZone().getPlayer(player_id);
480
+ };
481
+
482
+ /**
483
+ * 获取所有玩家对象
484
+ * @returns {Array} 玩家对象列表
485
+ */
486
+ Channel.prototype.getAllPlayers = function () {
487
+ var players = [];
488
+ for (var player_id of this.player_ids.keys()) {
489
+ var player = this.getPlayer(player_id);
490
+ players.push(player);
491
+ }
492
+ return players;
493
+ };
494
+
495
+ /**
496
+ * 创建房间
497
+ * @param {string} name 房间名称
498
+ * @param {string} player_id 玩家ID
499
+ * @returns {object} 创建的房间对象
500
+ */
501
+ Channel.prototype.createRoom = async function (name, player_id) {
502
+ if (!name) {
503
+ throw new TypeError('房间名称不能为空');
504
+ }
505
+
506
+ if (!player_id) {
507
+ throw new TypeError('玩家ID不能为空');
508
+ }
509
+
510
+ var player = this.getPlayer(player_id);
511
+ if (!player) {
512
+ throw new Error(`玩家 ${player_id} 不存在`);
513
+ }
514
+
515
+ let config = {
516
+ name,
517
+ 'min_level': player.level,
518
+ 'max_level': player.level + 100
519
+ };
520
+
521
+ var room = await this.roomAdmin.create(config, player_id);
522
+ return room;
523
+ };
524
+
525
+ /**
526
+ * 销毁房间
527
+ * @param {string} room_id 房间ID
528
+ * @returns {boolean} 是否成功销毁
529
+ */
530
+ Channel.prototype.destroyRoom = async function (room_id) {
531
+ if (!room_id) {
532
+ throw new TypeError('房间ID不能为空');
533
+ }
534
+
535
+ this.roomAdmin.del(room_id);
536
+ return true;
537
+ };
538
+
539
+ /**
540
+ * 玩家进入房间
541
+ * @param {string} room_id 房间ID
542
+ * @param {string} player_id 玩家ID
543
+ */
544
+ Channel.prototype.enterRoom = function (room_id, player_id) {
545
+ this.roomAdmin.enter(room_id, player_id);
546
+ };
547
+
548
+ /**
549
+ * 玩家退出房间
550
+ * @param {string} room_id 房间ID
551
+ * @param {string} player_id 玩家ID
552
+ */
553
+ Channel.prototype.leaveRoom = function (room_id, player_id) {
554
+ this.roomAdmin.leave(room_id, player_id);
555
+ };
556
+
557
+ /**
558
+ * 获取房间列表
559
+ * @returns {Array} 房间列表
560
+ */
561
+ Channel.prototype.getRoomList = function () {
562
+ return this.roomAdmin.getList();
563
+ };
564
+
565
+ /**
566
+ * 玩家开始实时匹配
567
+ * @param {string} player_id 玩家ID
568
+ * @param {object} options 匹配选项
569
+ * @returns {object} 匹配状态
570
+ */
571
+ Channel.prototype.startQuickMatch = function (player_id, options = {}) {
572
+ if (typeof player_id !== 'string') {
573
+ throw new TypeError('玩家ID必须是字符串');
574
+ }
575
+
576
+ var mode = options.mode || 'rank';
577
+ var format = options.format || '5v5';
578
+ var team_members = options.team_members || [player_id];
579
+ var team_size = team_members.length;
580
+
581
+ if (team_size > this._getMaxTeamSize(format)) {
582
+ throw new Error(`队伍人数超过限制: ${team_size}`);
583
+ }
584
+
585
+ for (var i = 0; i < team_members.length; i++) {
586
+ if (this.matcher.has(team_members[i])) {
587
+ throw new Error(`玩家 ${team_members[i]} 已在匹配池中`);
588
+ }
589
+ }
590
+
591
+ this.matcher.join(player_id, {
592
+ mode: mode,
593
+ format: format,
594
+ team_size: team_size,
595
+ team_members: team_members
596
+ });
597
+
598
+ return this.matcher.getMatchStatus(player_id);
599
+ };
600
+
601
+ /**
602
+ * 玩家取消实时匹配
603
+ * @param {string} player_id 玩家ID
604
+ * @returns {boolean} 是否成功取消
605
+ */
606
+ Channel.prototype.cancelQuickMatch = function (player_id) {
607
+ if (typeof player_id !== 'string') {
608
+ throw new TypeError('玩家ID必须是字符串');
609
+ }
610
+
611
+ return this.matcher.leave(player_id);
612
+ };
613
+
614
+ /**
615
+ * 获取实时匹配状态
616
+ * @param {string} player_id 玩家ID
617
+ * @returns {object|null} 匹配状态
618
+ */
619
+ Channel.prototype.getQuickMatchStatus = function (player_id) {
620
+ return this.matcher.getMatchStatus(player_id);
621
+ };
622
+
623
+ /**
624
+ * 获取匹配统计信息
625
+ * @returns {object} 统计信息
626
+ */
627
+ Channel.prototype.getMatchStats = function () {
628
+ return {
629
+ waiting_count: this.matcher.getTotalWaiting(),
630
+ room_count: this.roomAdmin.getCount()
631
+ };
632
+ };
633
+
634
+ /**
635
+ * 获取最大队伍人数
636
+ * @param {string} format 比赛格式
637
+ * @returns {number} 最大队伍人数
638
+ */
639
+ Channel.prototype._getMaxTeamSize = function (format) {
640
+ var sizes = {
641
+ '1v1': 1,
642
+ '3v3': 3,
643
+ '5v5': 5
644
+ };
645
+ return sizes[format] || 5;
646
+ };
647
+
648
+ /**
649
+ * 广播频道消息
650
+ * @param {object} data 广播数据
651
+ * @param {string} data_type 数据类型
652
+ * @returns {boolean} 是否广播成功
653
+ */
654
+ Channel.prototype.broadcast = async function (data, data_type) {
655
+ if (!data) {
656
+ throw new TypeError('数据不能为空');
657
+ }
658
+
659
+ if (!data_type || typeof data_type !== 'string') {
660
+ throw new TypeError('数据类型必须是有效字符串');
661
+ }
662
+
663
+ // 触发广播事件,由业务层处理具体的广播逻辑
664
+ this.emitEvent('channel_broadcast', {
665
+ channel_id: this.config.name,
666
+ data: data,
667
+ data_type: data_type,
668
+ timestamp: Date.now()
669
+ });
670
+
671
+ return true;
672
+ };
673
+
674
+ /**
675
+ * 发送频道消息
676
+ * @param {string} player_id 发送者ID
677
+ * @param {string} content 消息内容
678
+ * @returns {boolean} 是否发送成功
679
+ */
680
+ Channel.prototype.sendMessage = async function (player_id, content) {
681
+ if (!player_id) {
682
+ throw new TypeError('发送者ID不能为空');
683
+ }
684
+
685
+ if (!content || typeof content !== 'string') {
686
+ throw new TypeError('消息内容必须是有效字符串');
687
+ }
688
+
689
+ if (!this.player_ids.has(player_id)) {
690
+ throw new Error('发送者不在当前频道中');
691
+ }
692
+
693
+ var player = this.getPlayer(player_id);
694
+
695
+ var msg = {
696
+ sender_id: player_id,
697
+ sender_name: player.name || player_id,
698
+ content: content,
699
+ msg_type: 'text',
700
+ msg_group: 'channel',
701
+ timestamp: Date.now(),
702
+ channel_id: this.config.name
703
+ };
704
+
705
+ // 触发消息发送事件,由业务层处理具体的发送逻辑
706
+ this.emitEvent('channel_message_send', msg);
707
+
708
+ return true;
709
+ };
710
+
711
+ /**
712
+ * 公共数据传输方法
713
+ * @param {string} sender_id 发送者ID
714
+ * @param {object} data 传输数据
715
+ * @param {string} data_type 数据类型
716
+ * @returns {object} 传输结果
717
+ */
718
+ Channel.prototype.send = async function (sender_id, data, data_type) {
719
+ // 触发数据发送事件,由业务层处理具体的发送逻辑
720
+ this.emitEvent('channel_data_send', {
721
+ channel_id: this.config.name,
722
+ sender_id: sender_id,
723
+ data: data,
724
+ data_type: data_type,
725
+ timestamp: Date.now()
726
+ });
727
+
728
+ // 返回默认结果
729
+ return {
730
+ players: this.player_ids.size,
731
+ success: 0,
732
+ fail: 0,
733
+ failed_players: []
734
+ };
735
+ };
736
+
737
+ /**
738
+ * 获取频道统计信息
739
+ * @returns {object} 统计信息
740
+ */
741
+ Channel.prototype.getStats = function () {
742
+ return {
743
+ ...this.stats,
744
+ channel_name: this.config.name,
745
+ channel_status: this.status,
746
+ channel_type: this.config.type,
747
+ current_time: Date.now()
748
+ };
749
+ };
750
+
751
+ /**
752
+ * 切换频道状态
753
+ * @param {number} new_status 新状态
754
+ * @returns {boolean} 是否切换成功
755
+ */
756
+ Channel.prototype.switchStatus = function (new_status) {
757
+ if (typeof new_status !== 'number' || new_status < 0 || new_status > 3) {
758
+ throw new TypeError('频道状态必须是0-3之间的数字');
759
+ }
760
+
761
+ var old_status = this.status;
762
+ this.status = new_status;
763
+
764
+ this.emitEvent('channel_status_changed', {
765
+ channel_id: this.config.name,
766
+ old_status: old_status,
767
+ new_status: new_status,
768
+ timestamp: Date.now()
769
+ });
770
+
771
+ this.log('info', `频道 ${this.channel_id} 状态切换: ${old_status} -> ${new_status}`);
772
+ return true;
773
+ };
774
+
775
+ /**
776
+ * 销毁频道
777
+ * @returns {boolean} 是否销毁成功
778
+ */
779
+ Channel.prototype.destroy = async function () {
780
+ if (this._monitorTimer) {
781
+ clearInterval(this._monitorTimer);
782
+ }
783
+
784
+ for (var player_id of this.player_ids.keys()) {
785
+ await this.kickPlayer(player_id, '频道关闭');
786
+ }
787
+
788
+ // 保存所有房间数据
789
+ await this._saveRooms();
790
+
791
+ for (var world_name of this.worlds.keys()) {
792
+ await this.destroyWorld(world_name);
793
+ }
794
+
795
+ for (var room_name of this.rooms.keys()) {
796
+ await this.destroyRoom(room_name);
797
+ }
798
+
799
+ if (this.matcher) {
800
+ this.matcher.stop();
801
+ }
802
+
803
+ if (this.roomAdmin) {
804
+ this.roomAdmin.destroy();
805
+ }
806
+
807
+ this.emitEvent('channel_destroyed', {
808
+ channel_id: this.channel_id,
809
+ timestamp: Date.now()
810
+ });
811
+ return true;
812
+ };
813
+
814
+ /**
815
+ * 保存所有房间数据
816
+ * @returns {Promise<void>}
817
+ */
818
+ Channel.prototype._saveRooms = async function () {
819
+ try {
820
+ var promises = [];
821
+ for (var room of this.roomAdmin._rooms.values()) {
822
+ promises.push(room.do('save'));
823
+ }
824
+ await Promise.all(promises);
825
+ this.log('info', `保存所有房间数据成功,共 ${this.roomAdmin._rooms.size} 个`);
826
+ } catch (error) {
827
+ this.log('error', `保存房间数据失败: `, error);
828
+ }
829
+ };
830
+
831
+ /**
832
+ * 获取频道玩家数量
833
+ * @returns {number} 玩家数量
834
+ */
835
+ Channel.prototype.getPlayerNum = function () {
836
+ return this.player_ids.size;
837
+ };
838
+
839
+ /**
840
+ * 进入主世界
841
+ * @param {string} player_id 玩家ID
842
+ */
843
+ Channel.prototype.enterMainWorld = function (player_id) {
844
+ this.enterWorld(player_id, this._main_world_id);
845
+ };
846
+
847
+ /**
848
+ * 进入世界
849
+ * @param {string} player_id 玩家ID
850
+ * @param {string} world_id 世界ID
851
+ * @returns {object} 世界对象
852
+ */
853
+ Channel.prototype.enterWorld = function (player_id, world_id) {
854
+ let world = this.getWorldById(world_id);
855
+ if (!world) {
856
+ throw new Error(`世界 ${world_id} 不存在`);
857
+ }
858
+ world.enter(player_id);
859
+ return world;
860
+ };
861
+
862
+ /**
863
+ * 根据世界ID获取世界对象
864
+ * @param {string} world_id 世界ID
865
+ * @returns {object|null} 世界对象
866
+ */
867
+ Channel.prototype.getWorldById = function (world_id) {
868
+ return this.worlds.get(world_id);
869
+ };
870
+
871
+ /**
872
+ * 根据世界名称获取世界对象
873
+ * @param {string} name 世界名称
874
+ * @returns {object|null} 世界对象
875
+ */
876
+ Channel.prototype.getWorldByName = function (name) {
877
+ for (let world of this.worlds.values()) {
878
+ if (world.config.name === name) {
879
+ return world;
880
+ }
881
+ }
882
+ return null;
883
+ };
884
+
885
+ /**
886
+ * 创建游戏世界
887
+ * @param {object} config 世界配置
888
+ * @param {string} world_id 世界ID
889
+ * @returns {object} 世界对象
890
+ */
891
+ Channel.prototype.createWorld = async function (config, world_id) {
892
+ // let game = this.game[config.type];
893
+ // if (!game) {
894
+ // throw new Error(`游戏类型 ${config.type} 不存在`);
895
+ // }
896
+ // return await game.createWorld(config, world_id);
897
+ };
898
+
899
+ exports.Channel = Channel;