UNPKG

16.6 kBJavaScriptView Raw
1/**
2 * bootstrap
3 */
4let httpProxy = require('http-proxy');
5let express = require('express');
6let EventEmitter = require('events').EventEmitter;
7EventEmitter.defaultMaxListeners = 0;
8
9//注入通用函数
10require('./util/mixin/base');
11
12// Uncaught exception handler
13process.on('uncaughtException', function(err) {
14 console.error(' Caught exceptio n: ' + err.stack);
15});
16
17let commonFunc = require('./util/commonFunc');
18let getAsnyc = require('./util/async')
19let cache = require('./util/cache')
20let formula = require('./util/formula')
21let Indicator = require('./util/Indicator')
22let updateMgr = require('./util/updateMgr')
23let Collection = require('./util/Collection')
24let config = require('./util/configInterface') //配置文件管理
25let {applyMixins, extendObj, clone} = require('./util/mixin/comm')
26let filelist = require('./util/filelist')
27let iniFile = require(`${process.cwd()}/gameconfig`);
28
29/**
30 * 门面对象
31 */
32class Facade
33{
34 /**
35 * 启动支持反向代理的静态门户网站
36 * @param {String} options.protocol 协议 http/https
37 * @param {Object} options.router 路由 {host: {target,}}
38 * @param {String} options.port 守护端口
39 */
40 static startProxy(options) {
41 // 新建一个代理 Proxy Server 对象
42 var proxy = httpProxy.createProxyServer({});
43 proxy.on('error', function (err, req, res) {
44 res.writeHead(500, {'Content-Type': 'text/plain'});
45 res.end('Something went wrong.');
46 });
47 // 在每次请求中,调用 proxy.web(req, res config) 方法进行请求分发
48 var server = (require(options.protocol||'http')).createServer(function(req, res) {
49 var host = req.headers.host, ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
50 if(options.router[host]) {
51 proxy.web(req, res, { target: options.router[host].target });
52 } else {
53 res.writeHead(200, {'Content-Type': 'text/plain'});
54 res.end('Welcome! visit [wallet.vallnet.cn] for wallet service and [crm.vallnet.cn] for crm service.');
55 }
56 });
57 server.listen(options.port);
58 }
59
60 /**
61 * 添加一个静态内容服务站
62 * @description 相比通过 facade.boot 传入 static 数组而言,该方法能灵活指定协议、地址和端口
63 *
64 * @param {*} protocol 协议 http / https
65 * @param {*} host 主机地址
66 * @param {*} port 主机端口
67 * @param {Object} route 路由设置
68 */
69 static addWebSite(protocol, host, port, route) {
70 let app = express();
71 if(Array.isArray(route)) {
72 route.map(rt=>{
73 app.use(rt.path, express.static(rt.dir));
74 });
75 }
76
77 let httpObj = require(protocol);
78 let hrv = httpObj.createServer(app);
79 hrv.listen(port, host, () => {
80 console.log(`静态网站服务在 ${protocol}://${host}:${port} 上准备就绪`);
81 });
82 }
83
84 /**
85 * 系统主引导流程
86 * @param {*} options 启动参数数组
87 */
88 static async boot(options, startup) {
89 this.serverType = {};
90 this.serverTypeMapping = {};
91
92 //自动从指定目录载入系统定义和用户自定义的核心类
93 let corelist = filelist.mapPackagePath(`${__dirname}/./core`);
94 if(this.$addition) {
95 corelist = corelist.concat(filelist.mapPath('app/core'));
96 }
97 corelist.map(srv => {
98 let srvObj = require(srv.path);
99 this.serverType[srv.name.split('.')[0]] = srvObj; //节点类列表
100 srvObj.mapping.map(key => {
101 this.serverTypeMapping[key] = srvObj; //节点类映射列表,每个节点类可能映射多个条目
102 });
103 });
104
105 //主程序启动,提供包括Http、Socket、路由解析等服务
106 let core = this.FactoryOfCore(!!options?options.env:{});
107 extendObj(core.options, options);
108
109 if(this.$addition) { //加载用户自定义模块
110 await core.loadModel();
111 }
112
113 //将用户自定义表添加到自动加载列表中
114 if(options.loading) {
115 options.loading.map(table=>{
116 core.addLoadingModel(table);
117 });
118 }
119
120 let app = express();
121 //启用跨域访问
122 app.all('*',function (req, res, next) {
123 // 允许应用的跨域访问
124 res.header('Access-Control-Allow-Origin', '*');
125 res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
126 res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
127
128 if (req.method == 'OPTIONS') {
129 //让options请求快速返回
130 res.send(200);
131 } else {
132 next();
133 }
134 });
135
136 //region 添加POST模式下的body解析器
137 let bodyParser = require('body-parser');
138 app.use(bodyParser.urlencoded({extended: true}))
139 app.use(bodyParser.json());
140 //endregion
141
142 //载入持久化层数据,开放通讯服务端口,加载所有控制器相关的路由、中间件设定
143 await core.Start(app);
144 core.app = app;
145
146 if(options.static) {
147 for(let [route, path] of options.static) {
148 app.use(route, express.static(path));
149 }
150 }
151
152 //下发404 必须在控制器路由、静态资源路由全部加载之后设定
153 app.use(function(req, res, next) {
154 res.status(404).send('Sorry cant find the path!');
155 });
156
157 //捕获并下发错误码 必须放在最后!
158 app.use(function(err, req, res, next) {
159 console.error(err.stack);
160 res.status(500).send('Something broke!');
161 });
162
163 if(typeof startup == 'function') {
164 await startup(core);
165 }
166
167 return core;
168 }
169
170 /**
171 * 创建核心类实例的类工厂
172 * @param {*} env 运行环境
173 */
174 static FactoryOfCore(env) {
175 let ret = null;
176 if(!!this.serverTypeMapping[env.serverType] && !!this.ini.servers[env.serverType] && !!this.ini.servers[env.serverType][env["serverId"]]) {
177 ret = new this.serverTypeMapping[env.serverType](this.tools.extend(
178 {serverType: env.serverType, serverId: env.serverId},
179 this.ini.servers["Index"][1],
180 this.ini.servers[env.serverType][env["serverId"]]
181 ));
182 } else {
183 throw new Error(`无法识别的服务器类型和编号 ${env.serverType}.${env.serverId}`);
184 }
185 return ret;
186 }
187
188 /**
189 * 读取加载附加自定义模块标志
190 */
191 static get addition() {
192 return this.$addition || false;
193 }
194 /**
195 * 设置加载附加自定义模块标志,链式操作
196 */
197 static set addition(val) {
198 this.$addition = val;
199 return this;
200 }
201
202 /**
203 * 建立关键字和核心类之间的映射关系,用于建立核心对象的类工厂中
204 * @param {Array} pair 形如[keyword, CoreClassName]的数组
205 *
206 * @note 核心类的静态mapping方法规定了服务器类型映射关系,但可以随时调用registerServer补充新的映射关系
207 */
208 static registerServer(pair) {
209 if(!!pair) { //带参数表示补录映射关系
210 this.serverTypeMapping[pair[0]] = pair[1];
211 }
212 }
213
214 /**
215 * 获取当前运行环境的节点对象
216 */
217 static get current(){
218 return this.$current;
219 }
220 /**
221 * 设置当前运行环境的节点对象
222 */
223 static set current(val){
224 this.$current = val;
225 return this.$current;
226 }
227
228 //region 内置的节点类
229 static get CoreOfBase() {
230 return require('./core/CoreOfBase');
231 }
232 static get CoreOfIndex() {
233 return require('./core/CoreOfIndex');
234 }
235 static get CoreOfLogic() {
236 return require('./core/CoreOfLogic');
237 }
238 //endregion
239
240 //region 可用于继承的基础类
241
242 /**
243 * 集合管理类
244 */
245 static get Collection(){
246 return Collection;
247 }
248
249 /**
250 * 基础控制器类
251 */
252 static get Control(){
253 return require('./util/baseCtl');
254 }
255 /**
256 * 基础服务类
257 */
258 static get Service(){
259 return require('./util/baseService');
260 }
261 /**
262 * 基础助手类
263 */
264 static get Assistant(){
265 return require('./model/baseAssistant');
266 }
267
268 /**
269 * 背包管理基础类
270 */
271 static get Assistants() {
272 return {
273 Pocket: require('./model/assistant/item'),
274 }
275 }
276
277 /**
278 * 指向原生基础实体类
279 */
280 static get BaseEntity(){
281 return require('./model/BaseEntity');
282 }
283
284 /**
285 * 指向原生基础用户类
286 */
287 static get BaseUserEntity() {
288 return require('./model/entity/BaseUserEntity');
289 }
290
291 /**
292 * 指向原生基础联盟类
293 */
294 static get BaseAllyObject() {
295 return require('./model/entity/BaseAllyObject');
296 }
297
298 /**
299 * 指向原生基础日志类
300 */
301 static get BaseLogEntity() {
302 return require('./model/entity/BuyLogEntity');
303 }
304
305 //endregion
306
307 /**
308 * 返回全部助手类
309 */
310 static get assistants() {
311 if(!this.$assistants){
312 this.$assistants = {};
313 filelist.mapPackagePath(`${__dirname}/./model/assistant`).map(mod=>{
314 let mid = mod.name.split('.')[0];
315 this.$assistants[mid] = require(mod.path);
316 });
317 if(this.$addition) {
318 filelist.mapPath('app/model/assistant').map(mod=>{
319 let mid = mod.name.split('.')[0];
320 this.$assistants[mid] = require(mod.path);
321 });
322 }
323 }
324 return this.$assistants;
325 }
326 /**
327 * 返回全部表映射类
328 */
329 static get models() {
330 if(!this.$models){
331 //载入全部ORM模块
332 this.$models = {};
333 filelist.mapPackagePath(`${__dirname}/./model/table`).map(mod=>{
334 let mid = mod.name.split('.')[0];
335 this.$models[mid] = require(mod.path)[mid];
336 });
337 if(this.$addition) {
338 filelist.mapPath('app/model/table').map(mod=>{
339 let mid = mod.name.split('.')[0];
340 this.$models[mid] = require(mod.path)[mid];
341 });
342 }
343 }
344 return this.$models;
345 }
346 /**
347 * 返回全部 ORM 映射类
348 */
349 static get entities(){
350 if(!this.$entities) {
351 this.$entities = {};
352
353 //载入原生Entity模块
354 filelist.mapPackagePath(`${__dirname}/./model/entity`).map(mod=>{
355 let mid = mod.name.split('.')[0];
356 this.$entities[mid] = require(mod.path);
357 });
358 //将 UserEntity AllyObject 也指向原生模块
359 this.$entities.UserEntity = require('./model/entity/BaseUserEntity'); //指向原生定义的角色类
360 this.$entities.AllyObject = require('./model/entity/BaseAllyObject'); //指向原生定义的联盟类
361
362 if(this.$addition) {
363 //载入用户自定义Entity模块,如果用户有重载 UserEntity AllyObject 则自动覆盖之前的设置
364 filelist.mapPath('app/model/entity').map(mod=>{
365 let mid = mod.name.split('.')[0];
366 this.$entities[mid] = require(mod.path);
367 });
368 }
369 }
370 return this.$entities;
371 }
372
373 /**
374 * 工具箱
375 */
376 static get tools() {
377 return {
378 mixin: applyMixins, //混合对象属性函数
379 extend: extendObj, //扩展对象函数
380 clone: clone, //深度复刻对象函数
381 Sequelize: require('sequelize'), //sequelize类
382 seqconn: require('./util/sequel'), //mysql连接器
383 maintain: require('./util/maintain'), //执行数据维护任务
384 formula: formula, //表达式计算
385 cache: cache, //缓存管理
386 Indicator: Indicator, //标志位管理
387 updateMgr: updateMgr, //定时刷新器
388 getAsnyc: getAsnyc,
389 Lock: require('./util/Lock')
390 };
391 }
392
393 /**
394 * 所有自动化执行类的列表
395 */
396 static get autoExec() {
397 if(!this.$autoExec){
398 this.$autoExec = {};
399 filelist.mapPackagePath(`${__dirname}/./util/autoExec`).map(mod=>{
400 let mid = mod.name.split('.')[0];
401 this.$autoExec[mid] = require(mod.path);
402 });
403 if(this.$addition) {
404 filelist.mapPath('app/util/autoExec').map(mod=>{
405 let mid = mod.name.split('.')[0];
406 this.$autoExec[mid] = require(mod.path);
407 });
408 }
409 }
410 return this.$autoExec;
411 }
412
413 /**
414 * 返回运行环境配置文件
415 */
416 static get ini(){
417 return iniFile;
418 }
419 /**
420 * 业务配置文件管理
421 */
422 static get config(){
423 return config;
424 }
425 /**
426 * 获取常用函数集
427 */
428 static get util(){
429 return commonFunc;
430 }
431 /**
432 * 获取常用枚举集
433 */
434 static get const(){
435 if(!this.$constList) {
436 //加载核心常量定义
437 this.$constList = require( './define/comm');
438 //加载扩展常量定义
439 for(let fl of filelist.mapPackagePath(`${__dirname}/./define`)){
440 let id = fl.name.split('.')[0];
441 if(id != 'comm'){
442 let n = require(fl.path);
443 extendObj(this.$constList, n);
444 }
445 }
446
447 if(this.$addition) {
448 //加载用户自定义常量定义
449 for(let fl of filelist.mapPath('app/define')){
450 let n = require(fl.path);
451 extendObj(this.$constList, n);
452 }
453 }
454
455 this.$constList.AddConditionType = (name, val) => {
456 this.$constList.em_Condition_Type[name] = val;
457 };
458 this.$constList.AddResType = (name, val) => {
459 this.$constList.ResType[name] = val;
460 };
461 }
462
463 return this.$constList;
464 }
465}
466
467class Util
468{
469 static get BonusObject() {
470 return require('./util/comm/BonusObject');
471 }
472
473 static get EffectManager() {
474 return require('./util/comm/EffectManager');
475 }
476
477 static get EffectObject() {
478 return require('./util/comm/EffectObject');
479 }
480
481 static get TollgateObject() {
482 return require('./util/tollgate/TollgateObject');
483 }
484
485 static get OperationInfo() {
486 return require('./util/tollgate/OperationInfo');
487 }
488
489 static get PotentialClientItem() {
490 return require('./util/potential/PetClientItem');
491 }
492
493 static get BattleManager() {
494 return require('./util/battle/BattleManager');
495 }
496
497 static get BaseBattleParam() {
498 let {BaseBattleParam} = require('./util/battle/util');
499 return BaseBattleParam;
500 }
501
502 static get BattleHero() {
503 let {BattleHero} = require('./util/battle/hero');
504 return BattleHero;
505 }
506
507 static get LargeNumberCalculator() {
508 return require('./util/comm/LargeNumberCalculator');
509 }
510
511 static get EventData() {
512 let {EventData} = require('./util/comm/EventData');
513 return EventData;
514 }
515}
516
517Facade.Util = Util;
518
519exports = module.exports = Facade;