'use strict'; var execFile = require('child_process').execFile; var phantomjs = require('phantomjs-prebuilt'); var request = require('request'); var svg2png = require('svg2png'); var md5 = require("md5") var path = require('path'); console.log('svg2png 加载成功', svg2png.version); var https = require('https'); var Jimp = require('jimp'); var fs = require('fs'); var uuid = require('node-uuid'); var util = require('util'); var quick = require('quick-pomelo'); var P = quick.Promise; var logger = quick.logger.getLogger('connector', __filename); var C = require('../../../../share/constant'); // var compateDate = require('../../../../share/compateDate'); var phantomjsCmd = phantomjs.path; console.log('PhantomJS 路径:', phantomjsCmd); var Handler = function (app) { this.app = app; // this.lcompateDate = new compateDate(); }; module.exports = function (app) { return new Handler(app); }; var proto = Handler.prototype; // RPC proto.getRpc = function (gameId) { console.log("----进入游戏房间++++++++++++++++++++",gameId) switch (gameId) { case 10006: return this.app.rpc.game.csjiangRemote; // 湖南长沙 case 10007: return this.app.rpc.game.sxjiangRemote; // 湖南红中 case 10008: return this.app.rpc.game.paodekuaiRemote; // 湖南跑得快 case 10005: return this.app.rpc.game.shuiguoRemote; // 湖南水果 case 10004: return this.app.rpc.game.paohuziRemote; // 湖南跑胡子 } }; proto.convertSvgToPng1 = P.coroutine(function* (svgPath, pngPath,cb) { // 拼接 PhantomJS 要执行的参数:转换脚本、SVG 路径、PNG 路径、缩放比例 var args = [ path.join(__dirname, 'converter.js'), // 转换脚本路径 svgPath, pngPath, scale ]; // 执行 PhantomJS 命令(核心!Node 调用子进程执行 PhantomJS) execFile(phantomjsCmd, args, function(err, stdout, stderr) { if (err) { cb(new Error('PhantomJS 执行失败:' + err.message)); } else if (stderr) { cb(new Error('PhantomJS 错误输出:' + stderr)); } else if (stdout) { cb(new Error('PhantomJS 标准输出:' + stdout)); } else { cb(null); // 转换成功 } }); }); proto.convertSvgToPng = P.coroutine(function* (svgPath, pngPath, scale, cb) { // 拼接 PhantomJS 要执行的参数:转换脚本、SVG 路径、PNG 路径、缩放比例 var args = [ "D:\\hnhzServer\\converter.js", //path.join(__dirname, 'converter.js'), // 转换脚本路径 "\./1.svg", pngPath, scale ]; console.warn(args) console.warn("phantomjsCmd:",phantomjsCmd) var targetCwd = "D:\\web\\root80\\image" // 执行 PhantomJS 命令(核心!Node 调用子进程执行 PhantomJS) execFile(phantomjsCmd, args, { cwd: targetCwd, // 关键!相当于执行 cd /d D:\hnhzServer\svg_temp timeout: 10000, // 10秒超时,防止卡死 encoding: 'utf8' }, function(err, stdout, stderr) { console.warn("err:",err," stdout:",stdout," stderr:",stderr) if (err) { cb(new Error('PhantomJS 执行失败:' + err.message)); } else if (stderr) { cb(new Error('PhantomJS 错误输出:' + stderr)); } else if (stdout) { //cb(new Error('PhantomJS 标准输出:' + stdout)); cb(null); } else { cb(null); // 转换成功 } }); }); proto.downloadSvg = P.coroutine(function* (svgUrl, savePath, cb) { var req = https.get(svgUrl, function(res) { if (res.statusCode !== 200) { return cb(new Error('下载 SVG 失败,状态码:' + res.statusCode)); } var stream = fs.createWriteStream(savePath); res.pipe(stream); stream.on('finish', function() { stream.close(function() { cb(null); // 下载完成,无错误 }); }); stream.on('error', function(err) { fs.unlink(savePath, function(){}); // 删除不完整文件 cb(err); }); }); req.on('error', cb); req.setTimeout(10000, function() { req.destroy(); cb(new Error('下载 SVG 超时')); }); }); var svgUrl = 'https://bargame.ala456.com/gameRes/1.svg'; // 目标 SVG 地址 var localSvgPath = 'D:\\web\\root80\\image\\1.svg'; // 本地 SVG 路径 var destPngPath = path.join("D:\\web\\root80\\image\\"); // 目标 PNG 路径 var requestGet = P.promisify(request.get, {multiArgs: true}); proto.fetchSvg = P.coroutine(function* (url, cb) { const client = url.startsWith('https') ? require('https') : require('http'); client.get(url, (res) => { if (res.statusCode !== 200) { cb(new Error('请求 SVG 失败,状态码: ' + res.statusCode)); res.resume(); return; } const chunks = []; res.on('data', (chunk) => chunks.push(chunk)); res.on('end', () => cb(null, Buffer.concat(chunks))); }).on('error', (e) => cb(e)); }); 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]; const width = 800; const height = 600; 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'); } console.warn("69") // 2. 使用 Jimp 读取 Buffer // 如果依然报 MIME 错误,可以尝试强制指定格式 (仅限确定是 jpg/png 的情况) svg2png(body, { width, height }, (err, buffer) => { console.warn("svg2png:",74) if (err) { console.warn('SVG 转 PNG 失败:', err); return; } console.warn("svg2png:",78) fs.writeFile('D:\\web\\root80\\image\\output.png', buffer, (err) => { if (err) console.warn('写出 PNG 失败:', err); else console.warn('输出 output.png 完成'); }); }); console.warn("84") } catch (error) { // 增加更详细的报错日志,方便排查 console.error('图片转换失败详情:', error.message); if (error.stack) console.error(error.stack); } }); // 登陆 proto.login = P.coroutine(function* (msg, session, next) { //{"hash":"eaf94f7eff192ff4eb49338bc2c5dd286034cf40b73df81dd4990d8ff3dea0bb","refOrderId":"ORDER20240228001","amount":0.01,"status":0,"message":"\u6210\u529F","fees":0,"feesU":0.123322,"timestamp":1772271039176,"sign":"968121dcd20682ab9dc296296b6aca46"} var self = this; if (session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_HAS_LOGGED }); } if (!msg._id) { return next(null, { code: C.ERROR, msg: C.PLAYER_HAS_LOGGED }); } let sgjconfig = yield this.app.models.SGJConfig.findByIdAsync('sgconfigs'); console.warn("sgjconfig:",sgjconfig) var istelegram = 0 if (sgjconfig) { istelegram = sgjconfig.istelegram; //排行榜已发奖励的日期(0点时间戳) // console.warn("获取水果机排行榜已发奖励的日期 ",this.phbyfjlrq); } if (istelegram) { console.warn("msg:",msg) if (!msg.istelegram || msg.istelegram !== 1) { return next(null, { code: C.SERVER_WEIHU, msg: C.PLAYER_HAS_LOGGED }); } } // console.warn("登陆+++++%s",msg._id,session.uid);//ts++ // console.warn("登陆+++++ "+ JSON.stringify(msg));//ts++ var playerId = msg._id; var isNew = 0; var ip = session.__session__.__socket__.remoteAddress.ip; let gameId2 = 0; if(msg.game){ if(msg.game == "mahjongsx"){ gameId2 = 10007; } else if(msg.game == "mahjongcs"){ gameId2 = 10006; } else if(msg.game == "paodekuai"){ gameId2 = 10008; } else if(msg.game == "shuiguo"){ gameId2 = 10005; } else if(msg.game == "paohuzi"){ gameId2 = 10004; } } // if(gameId2 == 0) gameId2 = 10007 let formId=0;//开源平台 0为微信 if (msg.formId) { formId=parseInt(msg.formId); } let isChange = false; let telStr = ""+msg.tel || ""; let pwdStr = ""+msg.pwd || ""; // console.warn("登陆+++++111%s",playerId);//ts++ var player = yield this.app.models.Player.findByIdAsync(playerId); // console.warn("登陆+++++222%s",msg._id);//ts++ if (!player) { // let idq11w = ""; // if(playerId.length == 18) idq11w = playerId.substr(0, 11);//_id前11位 // console.warn("登陆=== telStr: "+telStr+" idq11w "+idq11w); var yPlayers = []; if(telStr && telStr.length == 11) yPlayers = yield this.app.models.Player.findMongoAsync({ tel: telStr }); if (yPlayers.length > 1){ // console.warn("手机号被重复绑定=== telStr: ",yPlayers); return next(null, { code: C.ERROR, msg: 117 });//"手机号被重复绑定" } else if (yPlayers.length == 1){ if(pwdStr != yPlayers[0].pwd) { return next(null, { code: C.ERROR, msg: 118 });//"手机号的密码错误" } // console.warn("用手机号登陆成功: ",yPlayers[0]); playerId = yPlayers[0]._id; player = yPlayers[0]; isChange = true; } else if (yPlayers.length == 0 && playerId.length > 18){//按照手机号查不到用户 //换商户号同步方案 // console.warn("登陆++新用户",msg._id);//ts++ var oldPlayers = yield this.app.models.Player.findMongoAsync({ name: msg.name },'diamond'); if (oldPlayers.length > 0) { var diamond = oldPlayers[0].diamond; // console.warn("oldplayer", diamond); player = yield this.app.controllers.player.createAsync(playerId, msg.name, "1", msg.headurl,telStr,pwdStr, ip, msg.spread,formId,diamond);//ts++upd代理 spread } else { player = yield this.app.controllers.player.createAsync(playerId, msg.name, "1", msg.headurl,telStr,pwdStr, ip, msg.spread,formId);//ts++upd代理 spread } isNew = 1; } else{ return next(null, { code: C.ERROR, msg: 116 });//"目前暂未开放手机号注册新用户" } } else{ if(telStr && telStr.length == 11){ var yPlayers = yield this.app.models.Player.findMongoAsync({ tel: telStr }); if (yPlayers.length == 0){ if(player.tel != telStr){ player.tel = telStr; isChange = true; } if(player.pwd != pwdStr){ player.pwd = pwdStr; isChange = true; } } } } self.downloadSvg(svgUrl, localSvgPath, function(err) { console.log("96") if (err) { console.error('下载失败:', err.message); return; } console.log('SVG 已下载到:', localSvgPath); // 调用转换函数 self.convertSvgToPng(localSvgPath, destPngPath+playerId+".png", 1.0, function(err) { if (err) { console.error('转换 PNG 失败:', err.message); } else { console.log('转换成功!PNG 路径:', destPngPath); } }); }); console.warn("登陆+++++333%s",msg._id);//ts++ let playerIsEnable = 0; if(typeof(player.enable) == "undefined"){ playerIsEnable = 1; } else{ playerIsEnable = player.enable; } // console.warn("isNew ===== "+isNew+" registerTime "+player.registerTime); let tel = player.tel || ""; let pwd = player.pwd || ""; var result = yield this.app.controllers.player.connectAsync(playerId,msg.name,msg.headurl, session.frontendId, ip,msg.sex,formId); if (result.oldGameSvrId) { // console.warn("登陆+++++111 "+result.oldGameSvrId+" result.oldGameId "+result.oldGameId); let oldGameSvrId = result.oldGameSvrId; let gameRemote = this.getRpc(result.oldGameId); if (gameRemote) gameRemote.leaveTable.toServer(oldGameSvrId, playerId, () => { }); } if (result.oldConnectorId) { // console.warn("登陆+++++222 "+result.oldConnectorId); let oldConnectorId = result.oldConnectorId; let entryRemote = this.app.rpc.connector.entryRemote; yield P.promisify((cb) => entryRemote.kick({ frontendId: oldConnectorId }, playerId, (err, res) => cb(err, res)))(); } // if(player.rTableId>0) // { // //仅仅适用于开发的时候没有退出房间关掉服务器导致进不去房间的时候使用 // console.warn("登陆+++++333 player.rTableId "+player.rTableId); // player.tableId = ''; // player.gameId = 0; // player.gameServerId = ''; // player.rTableId = 0 // player.diamond =1000000; // yield player.saveAsync(); // } console.warn("登陆+++++444%s",msg._id);//ts++ var self = this; session.bind(playerId); session.on('closed', function (session, reason) { if (reason === 'kick' || !session.uid) { return; } // console.warn("entryHandler用户离开了?????111 "+session.uid); var goose = self.app.memdb.goose; goose.transaction(function () { return P.promisify(self.logout, self)({ closed: true }, session); }, self.app.getServerId()) .catch(function (e) { logger.error(e.stack); }); // }); // console.warn("登陆+++++555%s",msg._id);//ts++ //logger.info('player %s login', playerId); //let openId=player.openId;//充值时使用 //ts++代理属性 let agentId=''; let agentNo=String(player.userId); let agentName=player.name; //let connectUrl=player.myurl; let connectUrl=''; let form ='';//新用户来源(如果是来自于推广的链接这里存储agentNo) if(msg.agentId) { // console.warn("代理+++++",msg.agentId); var agenter = yield this.app.models.Agenter.findByIdReadOnlyAsync(msg.agentId,'agentNo agentName myUrl levelFlag enabled contact tel agentRate'); if (agenter) { // console.warn("代理 levelFlag "+agenter.levelFlag+" enabled "+ agenter.enabled+" contact " +agenter.contact+" tel "+agenter.tel+" agentRate "+ agenter.agentRate); let isEnable = 0; // let levelFlag = 0; if(typeof(agenter.enabled) == "undefined"){ isEnable = 1; } else{ isEnable = agenter.enabled;; } // if(typeof(agenter.levelFlag) == "undefined"){ // levelFlag = 1; // } // else{ // levelFlag = agenter.levelFlag; // } form=String(agenter.agentNo); // if(levelFlag != 2 && isEnable == 1){ if(isEnable == 1){ agentId=msg.agentId; agentNo=String(agenter.agentNo); agentName = agenter.agentName; connectUrl = agenter.myUrl; // if(player.mpId!= agenter.mpId)//重新读取 // { // openId=''; // } } } // console.warn("代理+++++:",agentName,connectUrl); } // if(player.formId!=0)//闲聊用户 // { // console.warn("闲聊用户+++++:"); // openId='xianliu'; // } // openId='111111111'; // console.warn("链接参数",msg.nid,msg.fid); // console.warn("登陆+++++666%s",msg._id);//ts++ let doid=0;//操作指令 let doroomid=0;//操作指令 let dodata=null;//操作数据 if(player.rTableId>0) { // console.warn("重入=== ",player.rTableId," gameId2 ",gameId2); let fjh = parseInt(player.rTableId)%100000; if(fjh >= 10000 && fjh < 30000) gameId2 = 10007; else if(fjh >= 30000 && fjh < 50000)gameId2 = 10006; else if(fjh >= 50000 && fjh < 70000)gameId2 = 10008; else if(fjh >= 50000 && fjh < 70000)gameId2 = 10008; else if(fjh >= 70000 && fjh < 80000)gameId2 = 10005; else if(fjh >= 80000 && fjh < 90000)gameId2 = 10004; // console.warn("重入111=== ",fjh," gameId2 ",gameId2); doid=1;//重入 dodata = { gameId: gameId2 }; doroomid = player.rTableId; } else { if (msg.fid) { let nid=parseInt(msg.nid); let fid=msg.fid; if (nid==0) { //console.warn("查询房间",fid); if(fid!="" && fid.length>7) { // logger.warn("login findByIdReadOnlyAsync fid111--------" + fid ); var record = yield this.app.models.FHMJTables.findByIdReadOnlyAsync(fid); if (!record) { // console.warn("这个房间没有战绩",fid); let room = fid.substr(fid.length - 7, fid.length)/////因为后六位为房间号 doid=2;//加入房间 dodata = { gameId: gameId2 }; doroomid = parseInt(room); // console.warn("下面功能疑似造成数据死锁故暂时去掉"); // let fjsfysc = 0;//房间是否已删除 // var gametable = yield this.app.models.GameTable.findByIdAsync(fid, '_id tableNo agentId type kind other playerCount round endMode'); // if(gametable){ // fjsfysc = gametable.endMode||0;//房间是否已删除 // // console.warn("这个房间有gametable",fjsfysc,gametable.endMode); // if(fjsfysc){ // // console.warn("这个房间有gametable设置为再来一局",fjsfysc); // doid=4;//再来一局 // dodata = { // tableId: String(gametable.tableNo), // gameId: gameId2, // upId: String(gametable._id), // round: String(gametable.round), // kind: String(gametable.kind), // playercount: String(gametable.playerCount), // type: String(gametable.type), // other: String(gametable.other), // agentId: String(gametable.agentId) // } // } // } // if(!fjsfysc){ // // console.warn("这个房间mei有gametable222这个房间没有被删除u ",fjsfysc); // let room = fid.substr(fid.length - 7, fid.length)/////因为后六位为房间号 // doid=2;//加入房间 // dodata = { // gameId: gameId2 // }; // doroomid = parseInt(room); // } //console.warn("加入房间",doroomid); } else { doid=3;//显示战绩 dodata = { _id:record._id, gameId: record.gameId, tableNo: record.tableNo, agentId: record.agentId, type: record.type, kind: record.kind, other: record.other, playerCount: record.playerCount, round: record.round, over: record.over, time: record.time, ctime: record.ctime, // sszjFile: record.sszjFile, sszj: record.sszj, users: record.users }; //console.warn("显示战绩数据",dodata); } } } else if(nid==1) { //console.warn("再来一局 查询房间",fid); if(fid!="" && fid.length>7) { // logger.warn("login findByIdReadOnlyAsync fid222--------" + fid ); var record = yield this.app.models.FHMJTables.findByIdReadOnlyAsync(fid,'_id gameId tableNo agentId type kind other playerCount round over ctime stime time endMode sszj users'); if (!record) { //console.warn("再来一局 没有战绩",fid); } else { doid=4;//再来一局 dodata = { tableId: String(record.tableNo), gameId: record.gameId, upId: String(record._id), round: String(record.round), kind: String(record.kind), playercount: String(record.playerCount), type: String(record.type), other: String(record.other), agentId: String(agentId) } // console.warn("再来一局数据",dodata); } } } } } ////TL++20200928,因为正式服的绝大多数玩家是没有记录推荐人这个字段(spreadId)的,一少部分记录的是推荐人的_id,一部分人记录的是推荐人userId ////为了统一,在这里玩家登录的时候对玩家的推荐人(spreadId)字段统一记录为该玩家推荐人的userId // console.warn("接下来修改玩家的推荐id msg. player. ",msg.spread,typeof msg.spread,player.spreadId,typeof player.spreadId); let spreadId = ""; if((msg.spread+"").length == 6){ let msgspread = parseInt(msg.spread)||0; if(msgspread >= 100000 && msgspread <= 999999) spreadId = msg.spread + "" } if(!spreadId) spreadId = "99999999"; if(spreadId){ let gwjdtjridsfhf = false;////该登陆玩家的推荐人id是否合法 if((player.spreadId+"").length == 6){ let playerspread = parseInt(player.spreadId)||0; if(playerspread >= 100000 && playerspread <= 999999){ // console.warn("推荐人是不是自己",playerspread == parseInt(spreadId)); ////推荐人不能是自己 if(playerspread != parseInt(player.userId)){ gwjdtjridsfhf = true; } else{ spreadId = "99999999"; } } } else if((player.spreadId+"").length == 0){ if(parseInt(spreadId) == player.userId){ spreadId = "99999999"; } } else if((player.spreadId+"").length == 8 && player.spreadId == "99999999"){ gwjdtjridsfhf = true;////推荐人是系统就不改了 } else if((player.spreadId+"").length > 8){ let spreader = yield this.app.models.Player.findByIdAsync(player.spreadId, 'userId'); if (spreader) { spreadId = spreader.userId+""; } else{ spreadId = "99999999"; } } // gwjdtjridsfhf = false; // spreadId = ""; // console.warn("合法吗???gwjdtjridsfhf ",gwjdtjridsfhf,"player",player.spreadId , "spreadId",spreadId); if(!gwjdtjridsfhf){////不合法需要修改 player.spreadId = spreadId; // console.warn("不合法需要修改呢",player.spreadId); if(isNew && form){ player.form = form; } isChange = true; } else{ if(isNew && form){ player.form = form; isChange = true; } } } else{ if(isNew && form){ player.form = form; isChange = true; } } if(isChange){ yield player.saveAsync(); } let nowTime = Date.now();///TL++ // console.warn("??????????? rId "+player.rTableId+" doid "+doid +" doroomid "+doroomid+" dodata "+JSON.stringify(dodata)); // console.warn("登陆+++++777 "+msg._id+" rId "+player.rTableId+" doid "+doid +" doroomid "+doroomid+" dodata "+JSON.stringify(dodata));//ts++ if(dodata == null){ dodata = { gameId: 0 }; } if(isNew){ //给邀请新人按比例送钻这个活动记录新用户的邀请人信息,测试的话可以不用判断isNew yield this.app.controllers.player.setNewerYQXXAsync(playerId, player.userId, parseInt(msg.spread)); } //在玩家登陆的时候给玩家发邮件,比如发送活动的奖励邮件等等 yield this.app.controllers.player.sendMailOnLoginAsync(playerId, player.userId); console.warn("登陆+++++888==================================下面是登陆返回了",playerId,player.userId); let taskQuan = 0 let sgjUser = yield this.app.models.SGJUser.findByIdAsync(playerId); if (sgjUser) { taskQuan = sgjUser.taskQuan.toFixed(2) } yield this.app.controllers.player.sendMailOnLoginAsync(playerId, player.userId); let whdata = yield this.app.models.WHstate.findByIdReadOnlyAsync('wh', 'whTip stateWH rebaterate yxndlbTime yxndlbTip'); var whtip = whdata.yxndlbTip var isweihu = 0 if (whdata.stateWH != 0) { isweihu = 1 whtip = whdata.whTip } console.warn("whtip:",whtip) return next(null, { code: C.OK, data: { isNew: isNew, player: { _id: player._id, account: player.account, userId: String(player.userId), name: player.name, headurl:player.headurl, taskQuan:taskQuan, sex: player.sex, diamond: String(player.diamond), synPlayer:player.synPlayer, rId: String(player.rTableId), connectUrl: connectUrl, agentId: agentId, agentNo: agentNo, agentName: agentName, doid: String(doid), doroomid: String(doroomid), nowTime: nowTime, dodata: dodata, enabled: playerIsEnable, registerTime: player.registerTime, sfkjxyx: true,//是否可进小游戏 tel: tel, pwd: pwd, smName:player.smName, smCardId: player.smCardId, isweihu: isweihu, yxndlbTip:whtip, } } }); }); // 登出 proto.logout = P.coroutine(function* (msg, session, next) { // console.error("logout logout "+session.uid+" msg.closed "+msg.closed); if (!session.uid) { return next(null, { code: C.ERROR, msg: C.PLAYER_NOT_LOGIN }); } var playerId = session.uid; var result = yield this.app.controllers.player.disconnectAsync(playerId); if (result.gameSvrId) { let gameSvrId = result.gameSvrId; let gameRemote = this.getRpc(result.gameId) if (gameRemote) gameRemote.leaveTable.toServer(gameSvrId, playerId, () => { }); } else{ this.app.rpc.hall.hallRemote.leave.toServer("hall-server-1", playerId, () => { }); } if (!msg.closed) { yield P.promisify(session.unbind, session)(playerId); } logger.info('player %s logout', playerId); return next(null, { code: C.OK }); });