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