mm_os 4.3.7 → 5.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 (231) hide show
  1. package/README.md +102 -504
  2. package/index.js +26 -19
  3. package/lib/os.js +536 -0
  4. package/package.json +60 -84
  5. package/LICENSE +0 -21
  6. package/README_EN.md +0 -505
  7. package/adapter/adapter.js +0 -484
  8. package/adapter/custom_persistence.js +0 -661
  9. package/adapter/mqtt.js +0 -254
  10. package/adapter/socket.js +0 -244
  11. package/adapter/web.js +0 -92
  12. package/adapter/websocket.js +0 -43
  13. package/ai.js +0 -130
  14. package/com/api/README.md +0 -3
  15. package/com/api/com.json +0 -5
  16. package/com/api/config.tpl.json +0 -41
  17. package/com/api/drive.js +0 -732
  18. package/com/api/index.js +0 -201
  19. package/com/api/oauth.js +0 -200
  20. package/com/api/script.tpl.js +0 -32
  21. package/com/cmd/README.md +0 -11
  22. package/com/cmd/com.json +0 -5
  23. package/com/cmd/config.tpl.json +0 -48
  24. package/com/cmd/drive.js +0 -176
  25. package/com/cmd/index.js +0 -287
  26. package/com/cmd/job/config.json +0 -66
  27. package/com/cmd/job/index.js +0 -241
  28. package/com/cmd/job/test.js +0 -188
  29. package/com/cmd/msg.json +0 -48
  30. package/com/cmd/script.tpl.js +0 -12
  31. package/com/db/README.md +0 -3
  32. package/com/db/com.json +0 -5
  33. package/com/db/drive.js +0 -2206
  34. package/com/db/index.js +0 -241
  35. package/com/event/README.md +0 -4
  36. package/com/event/com.json +0 -5
  37. package/com/event/config.tpl.json +0 -20
  38. package/com/event/drive.js +0 -61
  39. package/com/event/index.js +0 -438
  40. package/com/event/script.tpl.js +0 -23
  41. package/com/mqtt/README.md +0 -47
  42. package/com/mqtt/com.json +0 -5
  43. package/com/mqtt/config.tpl.json +0 -42
  44. package/com/mqtt/drive.js +0 -704
  45. package/com/mqtt/index.js +0 -1052
  46. package/com/mqtt/index.test.js +0 -503
  47. package/com/mqtt/script.tpl.js +0 -719
  48. package/com/nav/README.md +0 -2
  49. package/com/nav/com.json +0 -5
  50. package/com/nav/config.tpl.json +0 -84
  51. package/com/nav/drive.js +0 -702
  52. package/com/nav/index.js +0 -228
  53. package/com/nav/tpl/admin_pc/page_channel.vue +0 -305
  54. package/com/nav/tpl/admin_pc/page_config.vue +0 -280
  55. package/com/nav/tpl/admin_pc/page_config_form.vue +0 -194
  56. package/com/nav/tpl/admin_pc/page_default.vue +0 -247
  57. package/com/nav/tpl/admin_pc/page_form.vue +0 -180
  58. package/com/nav/tpl/admin_pc/page_lang.vue +0 -264
  59. package/com/nav/tpl/admin_pc/page_nav.vue +0 -321
  60. package/com/nav/tpl/admin_pc/page_table.vue +0 -296
  61. package/com/nav/tpl/admin_pc/page_type.vue +0 -321
  62. package/com/nav/tpl/admin_pc/page_view.vue +0 -124
  63. package/com/nav/tpl/dev_pc/page_channel.vue +0 -253
  64. package/com/nav/tpl/dev_pc/page_config.vue +0 -253
  65. package/com/nav/tpl/dev_pc/page_default.vue +0 -247
  66. package/com/nav/tpl/dev_pc/page_form.vue +0 -162
  67. package/com/nav/tpl/dev_pc/page_nav.vue +0 -253
  68. package/com/nav/tpl/dev_pc/page_table.vue +0 -247
  69. package/com/nav/tpl/dev_pc/page_type.vue +0 -313
  70. package/com/nav/tpl/home_pc/page_channel.vue +0 -234
  71. package/com/nav/tpl/home_pc/page_default.vue +0 -234
  72. package/com/nav/tpl/home_pc/page_form.vue +0 -137
  73. package/com/nav/tpl/home_pc/page_list.vue +0 -234
  74. package/com/nav/tpl/home_pc/page_nav.vue +0 -221
  75. package/com/nav/tpl/home_pc/page_type.vue +0 -234
  76. package/com/nav/tpl/home_pc/page_view.vue +0 -125
  77. package/com/nav/tpl/home_phone/page_channel.vue +0 -234
  78. package/com/nav/tpl/home_phone/page_default.vue +0 -234
  79. package/com/nav/tpl/home_phone/page_form.vue +0 -137
  80. package/com/nav/tpl/home_phone/page_list.vue +0 -234
  81. package/com/nav/tpl/home_phone/page_nav.vue +0 -237
  82. package/com/nav/tpl/home_phone/page_type.vue +0 -234
  83. package/com/nav/tpl/home_phone/page_view.vue +0 -125
  84. package/com/nav/viewmodel.js +0 -446
  85. package/com/param/README.md +0 -2
  86. package/com/param/com.json +0 -5
  87. package/com/param/config.tpl.json +0 -136
  88. package/com/param/drive.js +0 -502
  89. package/com/param/index.js +0 -158
  90. package/com/param/script.tpl.js +0 -12
  91. package/com/pendant/README.md +0 -3
  92. package/com/pendant/com.json +0 -5
  93. package/com/pendant/config.tpl.json +0 -32
  94. package/com/pendant/drive.js +0 -204
  95. package/com/pendant/index.js +0 -467
  96. package/com/pendant/pendant.html +0 -16
  97. package/com/pendant/script.tpl.js +0 -18
  98. package/com/socket/README.md +0 -47
  99. package/com/socket/com.json +0 -5
  100. package/com/socket/config.tpl.json +0 -12
  101. package/com/socket/drive.js +0 -679
  102. package/com/socket/index.js +0 -402
  103. package/com/socket/script.tpl.js +0 -41
  104. package/com/sql/README.md +0 -3
  105. package/com/sql/com.json +0 -5
  106. package/com/sql/config.tpl.json +0 -74
  107. package/com/sql/drive.js +0 -1328
  108. package/com/sql/index.js +0 -152
  109. package/com/sql/script.tpl.js +0 -47
  110. package/com/static/README.md +0 -2
  111. package/com/static/com.json +0 -5
  112. package/com/static/config.tpl.json +0 -24
  113. package/com/static/drive.js +0 -194
  114. package/com/static/index.js +0 -237
  115. package/com/static/script.tpl.js +0 -28
  116. package/com/task/README.md +0 -3
  117. package/com/task/com.json +0 -5
  118. package/com/task/config.tpl.json +0 -24
  119. package/com/task/drive.js +0 -428
  120. package/com/task/index.js +0 -159
  121. package/com/task/script.tpl.js +0 -40
  122. package/com/template/com.json +0 -5
  123. package/com/template/config.tpl.json +0 -16
  124. package/com/template/drive.js +0 -81
  125. package/com/template/index.js +0 -141
  126. package/com.js +0 -237
  127. package/common/README.md +0 -2
  128. package/common/middleware/web_after/index.js +0 -26
  129. package/common/middleware/web_after/middleware.json +0 -9
  130. package/common/middleware/web_base/index.js +0 -113
  131. package/common/middleware/web_base/middleware.json +0 -19
  132. package/common/middleware/web_before/index.js +0 -33
  133. package/common/middleware/web_before/middleware.json +0 -9
  134. package/common/middleware/web_cors/index.js +0 -87
  135. package/common/middleware/web_cors/middleware.json +0 -24
  136. package/common/middleware/web_error/index.js +0 -131
  137. package/common/middleware/web_error/middleware.json +0 -19
  138. package/common/middleware/web_ip/index.js +0 -15
  139. package/common/middleware/web_ip/middleware.json +0 -14
  140. package/common/middleware/web_logger/index.js +0 -156
  141. package/common/middleware/web_logger/middleware.json +0 -14
  142. package/common/middleware/web_main/index.js +0 -26
  143. package/common/middleware/web_main/middleware.json +0 -9
  144. package/common/middleware/web_static/index.js +0 -73
  145. package/common/middleware/web_static/middleware.json +0 -54
  146. package/common/middleware/web_waf/index.js +0 -395
  147. package/common/middleware/web_waf/middleware.json +0 -13
  148. package/core/app/config.tpl.json +0 -67
  149. package/core/app/index.js +0 -711
  150. package/core/app/script.tpl.js +0 -52
  151. package/core/channel/index.js +0 -899
  152. package/core/channel/matcher.js +0 -585
  153. package/core/com/config.tpl.json +0 -16
  154. package/core/com/index.js +0 -77
  155. package/core/com/script.tpl.js +0 -5
  156. package/core/component/component.js +0 -42
  157. package/core/component/config.tpl.json +0 -63
  158. package/core/component/index.js +0 -273
  159. package/core/component/script.tpl.js +0 -19
  160. package/core/controller/config.tpl.json +0 -14
  161. package/core/controller/index.js +0 -371
  162. package/core/controller/script.tpl.js +0 -27
  163. package/core/factory/config.tpl.json +0 -14
  164. package/core/factory/entity.js +0 -275
  165. package/core/factory/index.js +0 -241
  166. package/core/factory/script.tpl.js +0 -16
  167. package/core/game/bat/index.js +0 -137
  168. package/core/game/bat/world.js +0 -622
  169. package/core/game/config.tpl.json +0 -16
  170. package/core/game/entity_admin.js +0 -230
  171. package/core/game/index.js +0 -186
  172. package/core/handler/config.tpl.json +0 -22
  173. package/core/handler/index.js +0 -181
  174. package/core/handler/script.tpl.js +0 -23
  175. package/core/logic/config.tpl.json +0 -14
  176. package/core/logic/index.js +0 -59
  177. package/core/logic/script.tpl.js +0 -19
  178. package/core/middleware/config.tpl.json +0 -16
  179. package/core/middleware/index.js +0 -117
  180. package/core/middleware/script.tpl.js +0 -37
  181. package/core/mod/config.tpl.json +0 -22
  182. package/core/mod/index.js +0 -136
  183. package/core/mod/script.tpl.js +0 -34
  184. package/core/model/config.tpl.json +0 -219
  185. package/core/model/index.js +0 -272
  186. package/core/model/model.js +0 -27
  187. package/core/model/script.tpl.js +0 -20
  188. package/core/notifier/config.tpl.json +0 -14
  189. package/core/notifier/index.js +0 -77
  190. package/core/notifier/script.tpl.js +0 -20
  191. package/core/plugin/config.tpl.json +0 -36
  192. package/core/plugin/index.js +0 -267
  193. package/core/plugin/script.tpl.js +0 -51
  194. package/core/pusher/config.tpl.json +0 -14
  195. package/core/pusher/index.js +0 -158
  196. package/core/pusher/script.tpl.js +0 -20
  197. package/core/room/bat/index.js +0 -170
  198. package/core/room/bat/room.js +0 -524
  199. package/core/room/config.tpl.json +0 -20
  200. package/core/room/index.js +0 -249
  201. package/core/room/room.js +0 -61
  202. package/core/scene/config.tpl.json +0 -14
  203. package/core/scene/index.js +0 -467
  204. package/core/scene/loop.js +0 -1306
  205. package/core/scene/map.js +0 -28
  206. package/core/scene/script.tpl.js +0 -22
  207. package/core/sender/config.tpl.json +0 -14
  208. package/core/sender/index.js +0 -79
  209. package/core/sender/script.tpl.js +0 -20
  210. package/core/service/config.tpl.json +0 -14
  211. package/core/service/index.js +0 -100
  212. package/core/service/script.tpl.js +0 -25
  213. package/core/store/config.tpl.json +0 -26
  214. package/core/store/index.js +0 -1794
  215. package/core/store/script.tpl.js +0 -22
  216. package/core/system/config.tpl.json +0 -18
  217. package/core/system/index.js +0 -312
  218. package/core/system/script.tpl.js +0 -77
  219. package/core/view/config.tpl.json +0 -14
  220. package/core/view/index.js +0 -91
  221. package/core/view/script.tpl.js +0 -20
  222. package/core/zone/bat/index.js +0 -744
  223. package/core/zone/config.tpl.json +0 -54
  224. package/core/zone/index.js +0 -655
  225. package/core/zone/script.tpl.js +0 -10
  226. package/core/zone/zone_bat.js +0 -136
  227. package/core//345/237/272/347/261/273/346/250/241/345/235/227/346/270/205/345/215/225.md +0 -24
  228. package/os.js +0 -53
  229. package/server.js +0 -602
  230. package/ulits/id_gen.js +0 -134
  231. package/ulits/word.js +0 -206
@@ -1,622 +0,0 @@
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().getDir();
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;
@@ -1,16 +0,0 @@
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
- }