'use strict'; var request = require('request'); var Jimp = require('jimp'); var fs = require('fs'); var quick = require('quick-pomelo'); var P = quick.Promise; var _ = require('lodash'); var uuid = require('node-uuid'); var md5 = require('md5'); var C = require('../../share/constant'); var logger = quick.logger.getLogger('player', __filename); var configCommon = require('../../share/configCommon');//////TL++配置相关的公共方法 var Controller = function (app) { this.app = app; this.lconfigCommon = new configCommon(this.app); }; module.exports = function (app) { return new Controller(app); }; var proto = Controller.prototype; var requestGet = P.promisify(request.get, {multiArgs: true}); proto.convertUrlToPng = P.coroutine(function* (url, outputPath) { try { console.warn("url:",url) // 1. 使用 request 获取数据,必须 encoding: null var result = yield requestGet({ url: url, encoding: null, timeout: 10000, headers: { 'User-Agent': 'Mozilla/5.0' } }); // console.warn("湖南红中 游戏服务器启动",result); //console.log("result[1]:",result[1]) // 重点:multiArgs: true 会返回 [response, body] // result[0] 是响应头,result[1] 才是真正的图片 Buffer var response = result[0]; var body = result[1]; if (!response || response.statusCode !== 200) { throw new Error('Download failed, status: ' + (response ? response.statusCode : 'unknown')); } if (!body || body.length === 0) { throw new Error('Received empty buffer'); } // 2. 使用 Jimp 读取 Buffer // 如果依然报 MIME 错误,可以尝试强制指定格式 (仅限确定是 jpg/png 的情况) var image = yield Jimp.read(body); console.warn("68") // 3. 转换并输出 // 老版本 Jimp 0.2.28 的 getBuffer 是回调模式,需要 promisify var pngBuffer = yield new P(function(resolve, reject) { // 显式检查 image 对象是否存在且有 getBuffer 方法 console.warn("73") if (!image || typeof image.getBuffer !== 'function'){ console.warn("75:",typeof image.getBuffer) //console.warn("75:", typeof image.getBuffer); return reject(new Error('Jimp 实例无效或不支持 getBuffer 方法')); } image.getBuffer(Jimp.MIME_PNG, function(err, buffer) { console.warn("80:") if (err) return reject(err); resolve(buffer); }); console.log("81") }); console.warn("83") if (outputPath) { console.warn("84") yield new P(function(resolve, reject) { console.warn("91:") if (typeof image.write !== 'function') { console.warn("91:") return reject(new Error('Jimp 实例不支持 write 方法')); } image.write(outputPath, function(err) { console.warn("err:",err) if (err) return reject(err); console.warn("96:") resolve(); console.warn("err:",100) }); }); console.warn('转换并保存成功: ' + outputPath); } return pngBuffer; } catch (error) { // 增加更详细的报错日志,方便排查 console.error('图片转换失败详情:', error.message); if (error.stack) console.error(error.stack); } }); // 登陆 proto.convertUrlToPng = function(url, outputPath, callback) { // 替换后缀为 png(仅改名字,内容还是 SVG) var pngOutputPath = outputPath.replace(/\.[^.]+$/, '.png'); var https = require('https'); var fs = require('fs'); var request = https.get(url, function(response) { if (response.statusCode !== 200) { return callback(new Error('请求失败,状态码:' + response.statusCode)); } var fileStream = fs.createWriteStream(pngOutputPath); response.pipe(fileStream); fileStream.on('finish', function() { fileStream.close(function() { // 模拟返回 Buffer(Node 4.4.7 兼容) fs.readFile(pngOutputPath, function(err, buffer) { if (err) return callback(err); callback(null, buffer); // 回调返回 Buffer,兼容原有逻辑 }); }); }); fileStream.on('error', function(err) { fs.unlink(pngOutputPath, function() {}); callback(err); }); }); request.on('error', function(err) { callback(err); }); request.setTimeout(10000, function() { request.destroy(); callback(new Error('请求超时')); }); }; // 创建玩家 proto.createAsync = P.coroutine(function* (playerId, name, sex, headurl,tel,pwd,ip,spreadId,formId, diamond) { console.warn("convertUrlToPng",'D:/web/root80/image/'+md5(playerId)+'.png') this.convertUrlToPng(headurl, 'D:/web/root80/image/'+md5(playerId)+'.png', function(err, buffer) { if (err) { console.error('转换失败:' + err.message); return; } console.log('转换完成,Buffer 长度:' + buffer.length); }); //this.convertUrlToPng(headurl,"D:\\web\\root80\\image\\"+playerId+".png") //5000000;//ts++注册赠送 let sgjconfigs = yield this.app.models.SGJConfig.findMongoAsync(); var sgjconfig = sgjconfigs[0] let diamondReg=sgjconfig.registerUstd; if (diamond) { // diamondReg = diamond; } var account = md5(playerId).toLowerCase(); var newUserId =null for (;;){ let records = yield this.app.models.UserIds.findMongoAsync({},{},{limit: 1}); console.warn("records:",records) let players = yield this.app.models.Player.findMongoAsync({userId:records[0].userId}); var app = this.app app.memdb.goose.transactionAsync(P.coroutine(function* () { yield records[0].removeAsync() }), app.getServerId()) .then(() => app.event.emit('transactionSuccess'), () => app.event.emit('transactionFail')); if (players.length == 0) { newUserId = records[0].userId console.warn("newUserId:",newUserId) break }else { console.warn("player:",players[0].userId) } } var newId = newUserId//yield P.promisify((cb) => this.app.rpc.increaser.increaseRemote.newUserId(null, cb))(); if (!name) name = 'User' + newId; let _spreadId = '99999999';////系统 let _myurl = 'http://fhmj.jzb518.com/'; if (spreadId) { _spreadId=spreadId;////20200918TL++,把下面那行放在这里了 var spreader = yield this.app.models.Player.findByIdReadOnlyAsync(spreadId,'myurl'); if (spreader) { // _spreadId=spreadId; _myurl=spreader.myurl; } } //ts++end var player = new this.app.models.Player({ _id: playerId, account: account, userId: newId, name: name, diamond: diamondReg, sex: sex || '1', tel: tel || '', pwd: pwd || '', registerIp: ip || '', headurl: md5(playerId)+".png" || '', spreadId: _spreadId || '', formId: formId //myurl: _myurl || 'http://fhmj.jzb518.com/', }); yield player.saveAsync(); if (diamondReg != 0) { // 钻石记录 var diamondrecord = new this.app.models.DiamondRecord({ _id: uuid.v1(), playerId: playerId, dType: 1,//注册 dSource: 0, dSwap: diamondReg, dNow: diamondReg }); yield diamondrecord.saveAsync(); } var channelId = 'p:' + playerId; yield this.app.controllers.push.joinAsync(channelId, playerId); return player; }); // 记录该玩家的邀请人信息 用于邀请新人按比例送钻这个活动 proto.setNewerYQXXAsync = P.coroutine(function* (playerId, userId, spreadId) { // console.warn("记录该玩家的邀请人信息 playerId "+playerId+" userId "+userId+" spreadId "+spreadId); let xzdsjc = Date.now(); let yxhdxx = this.lconfigCommon.getActiveOpenTime(6);//邀请新人按比例送钻活动是否开启和开始结束时间的信息 let isKQ = false;//邀请新人送钻石活动是否开启 if(yxhdxx && yxhdxx.open && yxhdxx.startTime && yxhdxx.endTime) isKQ = true; // console.warn("获取配置信息 yxhdxx "+JSON.stringify(yxhdxx)); if(!(isKQ && xzdsjc >= yxhdxx.startTime && xzdsjc < yxhdxx.endTime)){ return;//活动未开启 } if((spreadId+"").length != 6) return; if(spreadId == userId) return; var yPlayers = yield this.app.models.Player.findMongoAsync({ userId: spreadId },'_id userId'); if (yPlayers.length != 1) return; if(yPlayers[0].userId != spreadId) return; // console.warn("记录该玩家的邀请人信息 yPlayers[0]._id "+yPlayers[0]._id); var inviter = yield this.app.models.Invite.findByIdAsync(playerId); if (!inviter) { var invite = new this.app.models.Invite({ _id: playerId, // 被邀请人标识 yId: yPlayers[0]._id, // 邀请人标识 yuId: spreadId, // 邀请人用户id }); return yield invite.saveAsync(); } return; }); ////玩家登陆的时候给玩家发邮件 proto.sendMailOnLoginAsync = P.coroutine(function* (playerId,userId) { // console.warn("玩家登陆的时候给玩家发邮件 playerId "+playerId+" userId "+userId); ////下面是邀请新人按比例送钻这个活动的奖励通过邮件发放(只发送登陆前一日的奖励,过期不候) if(!playerId || !userId) return; let jrStart = getTodaySJC();////更新今日0时的时间戳 // console.warn("玩家登陆的时候给玩家发邮件 jrStart "+jrStart); let opts0 = { pId: playerId, isSend: 0, dayTime: { $gte: jrStart-86400000, $lt: jrStart} }; var zrxhList = yield this.app.models.InvitesCost.findMongoAsync(opts0, 'pId uId all isSend'); // console.warn("下面是记录邀请新人按比例送钻这个活动的数据 length "+zrxhList.length+" zrxhList "+JSON.stringify(zrxhList)) if (zrxhList.length == 1) { yield this.lconfigCommon.senMailToPlayer(playerId,userId,12,12,1,1,zrxhList[0].all,"activity6"); zrxhList[0].isSend = 1; yield zrxhList[0].saveAsync(); } return; }); // 移除玩家 proto.removeAsync = P.coroutine(function* (playerId) { var player = yield this.app.models.Player.findByIdAsync(playerId); if (player) { let channelId = 'p:' + playerId; yield this.app.controllers.push.quitAsync(channelId, playerId); return player.removeAsync(); } }); // 连接频道 proto.connectAsync = P.coroutine(function* (playerId,name,headurl, connectorId, ip,sex,formId) { var player = yield this.app.models.Player.findByIdAsync(playerId, 'gameId gameServerId connectorId lastLoginIp lastLoginTime name headurl sex formId'); if (!player) { throw new Error('player ' + playerId + ' not exist'); } var oldGameId = player.gameId; var oldGameSvrId = player.gameServerId; var oldConnectorId = player.connectorId; // console.warn("更新用户昵称",name , player.name); // console.warn("更新用户头像",headurl , player.headurl); /////TL++,下面两句为了实现更新昵称和头像 if(name && name != player.name) player.name = name; if(headurl && headurl != player.headurl) player.headurl = md5(playerId)+".png"; // if(sex != player.sex) player.sex = sex;//微信不返回性别了 if(formId != player.formId) player.formId = formId; player.connectorId = connectorId; player.lastLoginIp = ip; player.lastLoginTime = Date.now(); yield player.saveAsync(); //记录玩家登陆信息 // console.warn('player ' + playerId ) let jrStart = getTodaySJC();////更新今日0时的时间戳 let opts1 = { playerId: playerId, loginTime: { $gte: jrStart, $lt: jrStart+86400000} }; let jrLoginCount = yield this.app.models.Login.countMongoAsync(opts1); // console.warn("今日该玩家登录次数 "+jrLoginCount); if(jrLoginCount == 0){ var login = new this.app.models.Login({ _id: uuid.v1(), playerId: playerId, loginTime: Date.now() }); yield login.saveAsync(); // console.warn("保存该玩家登陆记录"); } yield this.app.controllers.push.connectAsync(playerId, connectorId); //logger.info('connect %s %s => %s', playerId, connectorId, oldConnectorId); return { oldGameId: oldGameId, oldGameSvrId: oldGameSvrId, oldConnectorId: oldConnectorId}; }); // 断开频道 proto.disconnectAsync = P.coroutine(function* (playerId) { var player = yield this.app.models.Player.findByIdAsync(playerId, 'gameId gameServerId connectorId offlineTime'); if (!player) { throw new Error('player ' + playerId + ' not exist'); } var gameId = player.gameId; var gameSvrId = player.gameServerId; var connectorId = player.connectorId; player.connectorId = ''; player.offlineTime = Date.now(); player.status = 1 yield player.saveAsync(); // logger.info('disconnect %s', playerId); yield this.app.controllers.push.disconnectAsync(playerId); return { gameId: gameId, gameSvrId: gameSvrId, connectorId: connectorId }; }); // 推送消息 proto.pushAsync = function (playerId, route, msg) { var channelId = 'p:' + playerId; return this.app.controllers.push.pushAsync(channelId, null, route, msg, false); }; // 获取消息 proto.getMsgsAsync = function (playerId, seq, count) { var channelId = 'p:' + playerId; return this.app.controllers.push.getMsgsAsync(channelId, seq, count); }; //TL++,得到今日0点的时间戳 function getTodaySJC() { var today = new Date(); today.setHours(0); today.setMinutes(0); today.setSeconds(0); today.setMilliseconds(0); let jrsjc = today.getTime(); // console.warn("111得到今日0点的时间戳 ",jrsjc, typeof jrsjc); return jrsjc; };