| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524 |
- import Msg from "../utils/msg";
- import {
- RefreshToken,
- PackageName,
- ProductId,
- IosUrl,
- Account,
- ClientSecret,
- ClientId,
- ORDER_SIGN_KEY,
- } from "../config/thirdParams";
- import {
- generateOrderNumber,
- formatDate,
- getServerList,
- getClientIp,
- } from "../utils/common";
- import {PaymentHelper} from "../utils/PaymentHelper";
- import {SignatureVerifier} from "../utils/SignatureVerifier";
- import {ChannelConfigManager} from "../utils/ChannelConfigManager";
- import {getRoleInfoByUidAndServerId} from "../mongo/mongodb";
- // 导入依赖
- const CryptoJS = require("crypto-js");
- const Order = require("../model/OrderModel");
- const Server = require("../model/ServerModel");
- const System = require("../model/SystemModel");
- const User = require("../model/UserModel");
- const logger = require("../utils/log");
- const axios = require("axios");
- const {channelFactory} = require("../channels/factory/ChannelFactory");
- const {MianyouChannelHandler} = require("../channels/handlers/MianyouChannelHandler");
- /**
- * Google支付回调处理
- */
- const googleCallPay = async (ctx, config) => {
- let data = ctx.request.body;
- let orderId = data.orderId;
- let googleToken = data.purchaseToken;
- let out_trade_no = "";
- logger.info("Google支付回调参数:", {url: ctx.href, params: data});
- // 更新订单Token
- await Order.updateOrderToken(orderId, googleToken, "google");
- // 获取Google访问令牌
- const redisClient = ctx.redis.client;
- let access_token = await redisClient.get("access_token");
- if (!access_token) {
- logger.info("请求Google API获取token");
- const apiData = {
- grant_type: "refresh_token",
- client_id: ClientId,
- client_secret: ClientSecret,
- refresh_token: RefreshToken,
- };
- try {
- const response = await axios.post(
- "https://accounts.google.com/o/oauth2/token",
- apiData,
- {
- headers: {
- "Content-Type": "application/x-www-form-urlencoded",
- },
- }
- );
- logger.info("Google token响应:", {data: response.data});
- if (!response.data.access_token) {
- return PaymentHelper.DEFAULT_RESULT;
- }
- access_token = response.data.access_token;
- await redisClient.set("access_token", response.data.access_token);
- await redisClient.expire("access_token", 1800);
- } catch (error) {
- logger.error("获取Google token失败:", error);
- return PaymentHelper.DEFAULT_RESULT;
- }
- }
- if (!access_token) {
- return PaymentHelper.DEFAULT_RESULT;
- }
- // 验证订单
- const validation = await PaymentHelper.validateOrder(orderId);
- if (!validation.valid) {
- return {
- code: validation.message?.includes("重复发货") ? 1 : 0,
- msg: validation.message,
- };
- }
- const orderInfo = validation.orderInfo;
- // 验证Google订单
- const productId = ProductId + orderInfo.product_id;
- let apiUrl = `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${PackageName}/purchases/products/${productId}/tokens/${googleToken}?access_token=${access_token}`;
- let maxRetries = 3;
- let currentRetry = 0;
- let isCheck = false;
- // 使用循环进行重试
- while (currentRetry < maxRetries) {
- try {
- const googleRes = await axios.get(apiUrl, {
- headers: {
- "Content-Type": "application/x-www-form-urlencoded",
- },
- });
- logger.info("Google验证响应:", googleRes.data);
- if (googleRes.data.purchaseState == 0) {
- out_trade_no = googleRes.data.orderId;
- isCheck = true;
- break;
- }
- } catch (error) {
- logger.error("Google验证请求失败:", error);
- }
- currentRetry++;
- }
- if (!isCheck) {
- return PaymentHelper.DEFAULT_RESULT;
- }
- // 发货处理
- const result = await PaymentHelper.deliverOrder(
- orderInfo,
- ctx.request.ip,
- validation.url,
- out_trade_no
- );
- // 确认和消费Google订单
- try {
- // 确认订单
- let acknowledgeUrl = `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${PackageName}/purchases/products/${productId}/tokens/${googleToken}:acknowledge?access_token=${access_token}`;
- await axios.post(
- acknowledgeUrl,
- {developerPayload: ""},
- {headers: {"Content-Type": "application/json"}}
- );
- // 消费订单
- let consumeUrl = `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${PackageName}/purchases/products/${productId}/tokens/${googleToken}:consume?access_token=${access_token}`;
- await axios.post(
- consumeUrl,
- {developerPayload: ""},
- {headers: {"Content-Type": "application/json"}}
- );
- logger.info("Google订单处理完成:", {orderId: orderId});
- } catch (error) {
- logger.error("Google订单确认/消费失败:", error);
- // 即使确认/消费失败,我们仍然返回发货结果,因为发货可能已经成功
- }
- return result;
- };
- /**
- * Apple支付回调处理
- */
- const appleCallPay = async (ctx, config) => {
- let data = ctx.request.body;
- logger.info("Apple支付回调参数:", {url: ctx.href, params: data});
- if (!data.purchaseToken || !data.orderId) {
- return PaymentHelper.DEFAULT_RESULT;
- }
- let receipt_data = data.purchaseToken.replace(/ /g, "+");
- let orderId = data.orderId;
- let out_trade_no = orderId;
- // 更新订单Token
- await Order.updateOrderToken(orderId, receipt_data, "apple");
- // 验证Apple收据
- let maxRetries = 5;
- let currentRetry = 0;
- let isCheck = false;
- while (currentRetry < maxRetries) {
- try {
- const apiData = {
- "receipt-data": receipt_data,
- };
- const response = await axios.post(IosUrl, apiData, {
- headers: {
- "Content-Type": "application/json",
- },
- });
- logger.info(`Apple验证响应状态:${response.data.status}`);
- if (response.data.status == 0) {
- isCheck = true;
- break;
- }
- } catch (error) {
- logger.error("Apple验证请求失败:", error);
- }
- currentRetry++;
- }
- if (!isCheck) {
- logger.info(`Apple票据验证失败!`);
- return {code: 0, msg: "票据验证失败!"};
- }
- // 验证订单
- const validation = await PaymentHelper.validateOrder(orderId);
- if (!validation.valid) {
- return {
- code: validation.message?.includes("重复发货") ? 1 : 0,
- msg: validation.message,
- };
- }
- const orderInfo = validation.orderInfo;
- // 发货处理
- logger.info(`订单${orderId}通知游戏发货开始`);
- const result = await PaymentHelper.deliverOrder(
- orderInfo,
- ctx.request.ip,
- validation.url,
- out_trade_no
- );
- logger.info(`订单${orderId}通知游戏发货结束,结果:`, result);
- return result;
- };
- function splitString(input: string, separator: string): string[] {
- return input.split(separator);
- }
- //验证账号
- const checkUserToken = async (ctx) => {
- let ip = getClientIp(ctx);
- let {
- uid,
- channel_id,
- device_no,
- reg_device,
- device_type,
- device_model,
- device_version,
- system_version,
- } = ctx.request.body;
- const create_time = formatDate(new Date());
- const accountInfo = (await User.checkAccountIsExist(uid, channel_id))[0];
- let accountRes = null;
- let res = null;
- if (!accountInfo) {
- accountRes = await User.createAccount(
- uid,
- channel_id,
- ip,
- device_no,
- reg_device,
- create_time
- );
- if (accountRes.affectedRows <= 0) {
- return ApiController.fail("添加账户失败");
- }
- }
- res = await User.logAccountLogin(
- uid,
- ip,
- device_type,
- device_no,
- device_model,
- device_version,
- system_version,
- create_time,
- channel_id
- );
- if (res.affectedRows <= 0) {
- return ApiController.fail("添加日志失败");
- }
- return ApiController.success("请求成功", 1, false, {ip: ip});
- };
- class ApiController {
- /**
- * 生成成功响应
- * @param msg 成功消息
- * @param code 成功码,默认为1(部分API使用0表示成功)
- * @param useMessage 是否使用message字段而不是msg字段,默认为false
- * @param data 响应数据
- * @returns 标准化的成功响应对象
- */
- static success(
- msg: string = "请求成功",
- code: number = 1,
- useMessage: boolean = false,
- data: any = null
- ) {
- return {
- code: code,
- [useMessage ? "message" : "msg"]: msg,
- data: data,
- };
- }
- /**
- * 生成失败响应
- * @param msg 错误消息
- * @param code 错误码,默认为0
- * @param data 额外的错误数据
- * @param useMessage 是否使用message字段而不是msg字段,默认为false
- * @returns 标准化的失败响应对象
- */
- static fail(
- msg: string = "请求失败",
- code: number = 0,
- data: any = null,
- useMessage: boolean = false
- ) {
- return {
- code: code,
- [useMessage ? "message" : "msg"]: msg,
- data: data,
- };
- }
- async createOrder(ctx) {
- let {
- uid,
- level,
- amount,
- role_id,
- role_name,
- product_id,
- server_id,
- channel_id,
- } = ctx.request.body;
- logger.info("create params:", {params: ctx.request.body});
- if (
- !product_id ||
- !server_id ||
- !role_name ||
- !role_id ||
- !amount ||
- !uid ||
- !channel_id
- ) {
- ctx.body = ApiController.fail("参数错误,创建订单失败!!", -1);
- return;
- }
- const data = ctx.request.body;
- if (!SignatureVerifier.verifyMD5Sign(data, ORDER_SIGN_KEY)) {
- logger.error("创建订单签名验证失败");
- ctx.body = ApiController.fail("签名错误,创建订单失败!!", -1);
- return;
- }
- if (amount <= 0) {
- ctx.body = ApiController.fail("金额错误,创建订单失败!!", -1);
- return;
- }
- const orderId = generateOrderNumber(); // 生成一个长度为8的订单号
- const create_time = formatDate(new Date());
- const res = await Order.createOrder(
- orderId,
- uid,
- level,
- amount,
- role_id,
- role_name,
- product_id,
- server_id,
- channel_id,
- create_time
- );
- if (res.affectedRows > 0) {
- ctx.body = ApiController.success("创建订单成功", 0, false, orderId);
- } else {
- ctx.body = ApiController.fail("创建订单失败", -1, null);
- }
- logger.info("创建订单返回结果:", {params: ctx.body});
- }
- async checkUserToken(ctx) {
- let {channel_id} = ctx.request.body;
- const channelConfig = ChannelConfigManager.getConfig(channel_id);
- if (!channelConfig) {
- logger.info("未找到渠道配置:", {channel_id});
- ctx.body = {
- code: 0,
- msg: "未知渠道id",
- };
- return;
- }
- var result = await checkUserToken(ctx);
- ctx.body = result;
- }
- async thirdLogin(ctx) {
- const data = ctx.request.body;
- let channelId = parseInt(data.channel_id) || 1;
- const platform = data.platform; // 平台参数:ios、Android、miniapp、h5
- logger.info("thirdLogin请求参数:", {data, channelId, platform});
- // 渠道11和渠道12数据打通,统一使用渠道11
- if (channelId === 12) {
- channelId = 11;
- logger.info("渠道12映射到渠道11,平台参数:", platform);
- }
- // 获取渠道配置
- let channelConfig = ChannelConfigManager.getConfig(channelId);
- if (data.is_new == 1) {
- if (channelId == 6) {
- channelConfig = ChannelConfigManager.getConfig(999);
- }
- if (channelId == 1) {
- channelConfig = ChannelConfigManager.getConfig(9);
- }
- }
- if (!channelConfig) {
- logger.info("未找到渠道配置:", {channelId});
- ctx.body = ApiController.fail("未知渠道id");
- return;
- }
- // 从工厂获取对应的渠道处理器
- const handler = channelFactory.getHandler(channelId);
- if (!handler) {
- logger.info("未找到渠道处理器:", {channelId});
- ctx.body = ApiController.fail("未知渠道id");
- return;
- }
- logger.info("使用渠道处理器处理登录:", {
- channelId: channelId,
- channelName: channelConfig.name,
- platform: platform
- });
- // 调用渠道处理器的登录方法
- const result = await handler.handleLogin(ctx, channelConfig);
- // 在返回结果中添加平台信息
- if (result && result.data) {
- result.data.platform = platform || 'unknown';
- }
- // 根据不同渠道的返回格式要求处理结果
- ctx.body = result;
- }
- async callPay(ctx) {
- const data = ctx.request.body;
- let channelId = 1; // 默认渠道ID
- //打印回调参数
- logger.info("callPay支付回调参数:", {url: ctx.href, params: data, query: ctx.query});
- // 从请求中获取渠道ID
- if (ctx.query.channel_id) {
- channelId = parseInt(ctx.query.channel_id);
- }
- if (data.channel_id) {
- channelId = parseInt(data.channel_id);
- }
- logger.info("当前支付渠道id:", {channelId});
- // 获取渠道配置
- let channelConfig = ChannelConfigManager.getConfig(channelId);
- if (!channelConfig) {
- logger.info("未找到渠道配置:", {channelId});
- ctx.body = ApiController.fail("未知渠道id");
- return;
- }
- if (ctx.query.is_new && ctx.query.is_new == 1) {
- if (channelId == 6) {
- channelConfig = ChannelConfigManager.getConfig(999);
- }
- if (channelId == 1) {
- channelConfig = ChannelConfigManager.getConfig(9);
- }
- }
- const handler = channelFactory.getHandler(channelId);
- if (!handler) {
- logger.info("未找到渠道处理器:", {channelId});
- ctx.body = ApiController.fail("未知渠道id");
- return;
- }
- logger.info("使用渠道处理器处理支付:", {
- channelId: channelId,
- channelName: channelConfig.name,
- });
- // 调用渠道处理器的支付方法
- const result = await handler.handlePayment(ctx, channelConfig);
- // 根据不同渠道的返回格式要求处理结果
- switch (channelConfig.channelId) {
- case 6:
- ctx.body = result.code === 1 ? 1 : result.code;
- break;
- case 2:
- case 3:
- case 5:
- case 8:
- ctx.body = result.code === 1 ? "SUCCESS" : "Fail";
- break;
- case 7:
- ctx.body = result.code === 1 ? "success" : "fail";
- break;
- case 11:
- ctx.body = result.code === 1 ? "SUCCESS" : "Fail";
- break;
- case 12:
- ctx.body = result.code === 1 ? "SUCCESS" : "Fail";
- break;
- case 13:
- //{"status":0,"msg":"status 非 0 时,传入失败信息"}
- ctx.body = {status: result.code === 1 ? 0 : -1, msg: result.msg};
- break;
- case 17:
- // 华为渠道:成功返回 {"errCode": 0},失败返回 {"errCode": 1, "errMsg": "..."}
- if (result.code === 0 || result.code === 1) {
- // 发货成功
- ctx.body = {errCode: 0};
- } else {
- // 发货失败
- ctx.body = {errCode: 1, errMsg: result.msg || "发放失败"};
- }
- break;
- case 14:
- ctx.body = result.code === 1 ? "SUCCESS" : "Fail";
- break;
- default:
- ctx.body = result;
- }
- }
- async getServerList(ctx) {
- let tag = ctx.query.channel_id || 1;
- let data = ctx.request.body;
- let ip = getClientIp(ctx);
- // 尝试从渠道ID获取配置
- const channelConfig = ChannelConfigManager.getConfig(1);
- const signStr = data.timestamp + channelConfig.loginConfig?.signKey;
- let newSign = CryptoJS.MD5(signStr).toString();
- if (data.sign != newSign) {
- console.log("signStr:", signStr);
- logger.info(
- `签名错误: 签名串 ${signStr} newSign ${newSign} sign ${data.sign}`
- );
- ctx.body = ApiController.fail("签名错误");
- return;
- }
- let sort = data.sort == 0 ? "asc" : "desc";
- logger.info("区服接口", {ip: ip});
- const servers = await Server.getServerList(tag, 0, sort);
- let serverList = [];
- if (servers.length > 0) {
- servers.forEach(function (element) {
- let status = element.status;
- if ((status == 0 || status == 3) && element.white_list) {
- const list = element.white_list.split(",");
- if (list.length > 0) {
- if (list.includes(ip)) {
- status = 1;
- }
- }
- }
- serverList.push({
- serverId: element.id,
- serverName: element.name,
- });
- });
- }
- ctx.body = ApiController.success("成功", 1, false, serverList);
- }
- async getAllServerList(ctx) {
- let tag = ctx.query.channel_id || 1;
- let uid = ctx.query.uid || ctx.request.body?.uid; // uid是可选参数,支持GET和POST请求
- let ip = getClientIp(ctx);
- logger.info("getAllServerList 区服接口", {tag: tag, uid: uid, ip: ip});
- const servers = await Server.getAllServerList(tag, ip);
- // 如果提供了玩家ID,则查询每个服务器的角色信息;否则只返回基本服务器信息
- if (uid) {
- const {getRoleInfoByUidAndServerId} = require("../mongo/mongodb");
- // 为每个服务器添加角色信息
- const serversWithRoleInfo = await Promise.all(
- servers.map(async (server) => {
- try {
- const newUniqueTag = `${server.tag}|${server.sid}|${uid}`;
- const roleInfo = await getRoleInfoByUidAndServerId(newUniqueTag, server.db_name);
- return {
- ...server,
- roleName: roleInfo?.roleName || null,
- roleLevel: roleInfo?.roleLevel || null,
- head: roleInfo?.head || null,
- hasRole: !!roleInfo
- };
- } catch (error) {
- logger.error(`查询服务器${server.id}角色信息失败:`, error);
- return {
- ...server,
- roleName: null,
- roleLevel: null,
- head: null,
- hasRole: false
- };
- }
- })
- );
- ctx.body = serversWithRoleInfo;
- } else {
- ctx.body = servers;
- }
- }
- async enterServer(ctx) {
- let {uid, server_id, channel_id} = ctx.request.body;
- let url = await getServerList(server_id, channel_id || 1);
- if (!url) {
- ctx.body = ApiController.fail(`区服id错误: serverId ${server_id}`, -1);
- return;
- }
- logger.info("create params:", {params: ctx.request.body});
- if (!server_id || !uid) {
- ctx.body = ApiController.fail("参数错误!!", -1);
- return;
- }
- const create_time = formatDate(new Date());
- const serverInfo = (
- await Server.checkEnterServerByUid(uid, server_id, channel_id)
- )[0];
- let res = null;
- if (serverInfo) {
- res = await Server.updateEnterServer(serverInfo.id, create_time);
- } else {
- res = await Server.enterServer(uid, server_id, create_time, channel_id);
- }
- if (res.affectedRows > 0) {
- ctx.body = ApiController.success("请求成功", 0, true, "");
- } else {
- ctx.body = ApiController.fail("请求失败", -1, null, true);
- }
- }
- async getLastServerList(ctx) {
- let {uid, channel_id} = ctx.request.body;
- // uid是可选参数,如果不提供则只返回基本服务器信息
- let tag = channel_id || 1;
- let data = [];
- let isNewAccount = 1;
- let enterServerList = [];
- let ip = getClientIp(ctx);
- logger.info("getLastServerList 区服接口", {uid: uid, ip: ip});
- // 获取渠道配置
- const channelConfig = ChannelConfigManager.getConfig(tag);
- if (!channelConfig) {
- logger.info("未找到渠道配置:", {tag});
- ctx.body = ApiController.fail("未知渠道id");
- return;
- }
- // 如果提供了uid,查询用户进入过的服务器列表
- if (uid) {
- enterServerList = await Server.getEnterServerListByUid(uid, channel_id);
- }
- if (enterServerList.length > 0) {
- isNewAccount = 0;
- const servers = await Server.getAllServerList(tag, ip);
- const {getRoleInfoByUidAndServerId} = require("../mongo/mongodb");
- // 为每个进入过的服务器添加角色信息
- for (const element of enterServerList) {
- let roleInfo = null;
- // 只有在提供了uid时才查询角色信息
- if (uid) {
- try {
- const newUniqueTag = `${tag}|${element.server_id}|${uid}`;
- roleInfo = await getRoleInfoByUidAndServerId(newUniqueTag, element.db_name);
- } catch (error) {
- logger.error(`查询服务器${element.server_id}角色信息失败:`, error);
- }
- }
- data.push({
- channel: channelConfig.name, //渠道固定
- minSid: 1, //最小服务器
- maxSid: servers.length, //最大服务器 这里会控制 服务器列表显示的数量
- isNewAccount: isNewAccount, //1为新号 会弹出用户协议
- //以下是最近登陆的服务器 (不可为空 如果没有参数可以填最后一个区)
- sid: element.server_id || 1,
- id: element.server_id || 1,
- name: element.name || "1区",
- tips: element.tips || "",
- server: element.wss
- ? element.wss
- : `ws://${element.ip}:${element.port}`,
- status: element.status || 0,
- // 角色信息(只有在提供了uid时才包含)
- roleName: roleInfo?.roleName || null,
- roleLevel: roleInfo?.roleLevel || null,
- head: roleInfo?.head || null,
- hasRole: !!roleInfo
- });
- }
- logger.info("getLastServerList 区服接口 enterServerList", {
- enterServerList: enterServerList,
- });
- } else {
- const servers = await Server.getAllServerList(tag, ip);
- let roleInfo = null;
- if (servers.length > 0) {
- const serverInfo = servers[servers.length - 1];
- logger.info("getLastServerList 区服接口 serverInfo", {
- serverInfo: serverInfo,
- });
- // 只有在提供了uid时才查询最后一个服务器的角色信息
- if (uid) {
- const {getRoleInfoByUidAndServerId} = require("../mongo/mongodb");
- try {
- const newUniqueTag = `${serverInfo.tag}|${serverInfo.sid}|${uid}`;
- roleInfo = await getRoleInfoByUidAndServerId(newUniqueTag, serverInfo.db_name);
- } catch (error) {
- logger.error(`查询服务器${serverInfo.id}角色信息失败:`, error);
- }
- }
- data.push({
- channel: channelConfig.name, //渠道固定
- minSid: 1, //最小服务器
- maxSid: servers.length, //最大服务器 这里会控制 服务器列表显示的数量
- isNewAccount: isNewAccount, //1为新号 会弹出用户协议
- //以下是最近登陆的服务器 (不可为空 如果没有参数可以填最后一个区)
- sid: serverInfo.sid || 1,
- id: serverInfo.id || 1,
- name: serverInfo.name || "1区",
- tips: serverInfo.tips || "",
- server: serverInfo.server
- ? serverInfo.server
- : `ws://${serverInfo.ip}:${serverInfo.port}/`,
- status: serverInfo.status || 0,
- // 角色信息
- roleName: roleInfo?.roleName || null,
- roleLevel: roleInfo?.roleLevel || null,
- head: roleInfo?.head || null,
- hasRole: !!roleInfo
- });
- } else {
- data.push({
- channel: "未知", //渠道固定
- minSid: 1, //最小服务器
- maxSid: 10, //最大服务器 这里会控制 服务器列表显示的数量
- isNewAccount: isNewAccount, //1为新号 会弹出用户协议
- //以下是最近登陆的服务器 (不可为空 如果没有参数可以填最后一个区)
- sid: 1,
- id: 1,
- name: "1区",
- tips: "",
- server: "",
- status: 0,
- // 角色信息(新用户,无角色)
- roleName: null,
- roleLevel: null,
- head: null,
- hasRole: false
- });
- }
- }
- ctx.body = data;
- // ctx.body = ApiController.success("获取最近服务器列表成功", 1, false, data);
- }
- async getNotice(ctx) {
- let tag = ctx.query.channel_id || 1;
- let content = "";
- let content_wh = "";
- const system = await System.getSystemConfig(tag);
- if (system) {
- system.forEach((element) => {
- if (element.key == "content") {
- content = element.value;
- }
- if (element.key == "content_wh") {
- content_wh = element.value;
- }
- });
- }
- let notice_data = [
- {
- status: 1,
- content: content,
- content_wh: content_wh,
- },
- ];
- ctx.body = notice_data;
- // ctx.body = ApiController.success("获取公告成功", 1, false, notice_data);
- }
- // 维护服务器,踢掉所有玩家
- async maintenance(ctx) {
- let data = {
- channel_id: parseInt(ctx.query.channel_id),
- serverId: parseInt(ctx.query.serverId) || "",
- };
- logger.info("maintenance :", {channelId: data.channel_id});
- let url = await getServerList(data.serverId, data.channel_id || 1);
- if (!url) {
- ctx.body = ApiController.fail(`区服id错误: serverId ${data.serverId}`, 1);
- return;
- }
- let param = JSON.stringify({
- type: "kickAllUser",
- });
- let sendMsg = new Msg();
- sendMsg.connect(url, Account);
- new Promise((resolve) => {
- setTimeout(async () => {
- sendMsg.CG_TEST_PROTO("test", param);
- }, 1000);
- });
- ctx.body = ApiController.success("success", 0, false, null);
- }
- async maintenanceAll(ctx) {
- let channelId = parseInt(ctx.query.channel_id);
- let isMaintenance = ctx.query.isMaintenance;
- let key = ctx.query.key;
- logger.info("maintenanceAll :", {
- channelId: channelId,
- isMaintenance: isMaintenance,
- });
- if (key != "dsdadsadajkkjkxab") {
- ctx.body = ApiController.fail("无权使用", -1);
- return;
- }
- const servers = await Server.getAllServerList(channelId, "");
- logger.info("maintenanceAll servers:", {servers: servers});
- if (servers.length === 0) {
- ctx.body = ApiController.fail("不存在可操作区服", -1);
- return;
- }
- const serversId = servers.map((obj) => obj.id);
- if (isMaintenance == "true") {
- const res = await Server.updateServerStatus(serversId, 3);
- }
- servers.forEach(function (element) {
- let url = "ws://" + element.ip + ":" + element.port;
- if (!url) {
- ctx.body = ApiController.fail(`区服id错误: serverId ${element.id}`, 1);
- return;
- }
- let param = JSON.stringify({
- type: "kickAllUser",
- });
- // Msg.connect(url, Account);
- let sendMsg = new Msg();
- sendMsg.connect(url, Account);
- new Promise((resolve) => {
- setTimeout(async () => {
- sendMsg.CG_TEST_PROTO("test", param);
- }, 1000);
- });
- });
- logger.info("maintenanceAll 更新的区服id:", {serversId: serversId});
- ctx.body = ApiController.success("success", 0, false, null);
- }
- async sendMail(ctx) {
- let data = ctx.request.body;
- let url = await getServerList(data.serverId, data.channel_id || 1);
- if (!url) {
- ctx.body = ApiController.fail(`区服id错误: serverId ${data.serverId}`, 1);
- return;
- }
- let param = JSON.stringify({
- type: "sendMail",
- mail: JSON.stringify({
- uuid: data.uuid,
- title: data.title,
- content: data.content,
- items: JSON.parse(data.items),
- expire: data.expire,
- }),
- });
- // Msg.connect(url, Account);
- let sendMsg = new Msg();
- sendMsg.connect(url, Account);
- new Promise((resolve) => {
- setTimeout(async () => {
- sendMsg.CG_TEST_PROTO("test", param);
- }, 1000);
- });
- ctx.body = ApiController.success("success", 0, false, null);
- }
- async sendAllMail(ctx) {
- let data = ctx.request.body;
- if (!data.server_list || data.server_list.length === 0) {
- ctx.body = ApiController.fail("区服不能为空", -1);
- return;
- }
- logger.info("sendAllMail 接口请求 data:", {data: data});
- const server_list = data.server_list;
- const servers = await Server.getServerList(data.channel_id || 1);
- const filteredServer = servers.filter((item) =>
- server_list.includes(item.id)
- );
- filteredServer.forEach(function (element) {
- let url = "ws://" + element.ip + ":" + element.port;
- if (!url) {
- ctx.body = ApiController.fail(
- `区服id错误: serverId ${element.server_id}`,
- 1
- );
- return;
- }
- let param = JSON.stringify({
- type: "sendAllMail",
- mail: JSON.stringify({
- title: data.title,
- content: data.content,
- items: JSON.parse(data.items),
- expire: data.expire,
- }),
- });
- let sendMsg = new Msg();
- sendMsg.connect(url, Account);
- new Promise((resolve) => {
- setTimeout(async () => {
- sendMsg.CG_TEST_PROTO("test", param);
- }, 1000);
- });
- });
- ctx.body = ApiController.success("success", 0);
- }
- async useCDKV2(ctx) {
- let body = ctx.request.body;
- logger.info("useCDKV2接口请求参数:", {data: body});
- let data = {
- code: body.code,
- userId: body.account,
- channelId: body.channel_id || 0,
- };
- if (body.uuid) {
- data.userId = body.uuid;
- }
- let serverUrl = await getServerList(body.serverId, body.channel_id);
- let err = "";
- if (!serverUrl) {
- ctx.body = ApiController.fail(`区服id错误: serverId ${body.serverId}`, 1);
- return;
- }
- let port = 8004;
- let host = "127.0.0.1";
- let url = "http://" + host + ":" + port + "/api/giftCode/exchange";
- logger.info("接口请求后台 data:", {data: data, url: url});
- try {
- const specialCodes = [
- "gfyx555",
- "gfyx666",
- "gfyx777",
- "gfyx1000",
- "gfyx2000",
- "gfyx3000",
- "gfyxrqlb",
- "GFYX555",
- "GFYX666",
- "GFYX777",
- "GFYX1000",
- "GFYX2000",
- "GFYX3000",
- "GFYXrqlb",
- "GFYX000",
- "GFYX222",
- "GFYX333",
- "GFYX888",
- "GFYX1818",
- "GQ888",
- "ZQ888",
- "gfyx8888",
- "gfyx6666",
- "gfyx7777",
- "gfyxxjbc",
- "LIDONGLB",
- "XIAOXULB",
- "GANENLB",
- "WANSHLB",
- "HERO666",
- "HERO777",
- "HERO888",
- "gfyx9999",
- "aiqi6666",
- "aiqi7777",
- "aiqi8888",
- "aiqi9999",
- "gf555",
- "gf666",
- "gf777",
- "gf100",
- "gf200",
- "gf300",
- "YDKL888",
- "SDKL888",
- ];
- let param: string = "";
- const h5Codes = ["gfyx000", "gfyx222", "gfyx333", "gfyx888", "gfyx1818"];
- if (h5Codes.includes(data.code) && body.channel_id != 5) {
- ctx.body = ApiController.fail("该激活码无法在h5渠道使用", 1);
- }
- if (specialCodes.includes(data.code) || h5Codes.includes(data.code)) {
- param = JSON.stringify({
- code: data.code,
- type: "UseFixCDK",
- channel_id: body.channel_id,
- });
- } else {
- const response = await axios.post(url, data, {
- headers: {
- "Content-Type": "application/json",
- },
- timeout: 10000,
- });
- logger.info("接口请求后台 接口返回 response:", {data: response.data});
- if (response.data.code != 200) {
- ctx.body = ApiController.fail(response.data.msg, 1);
- return;
- }
- const result = splitString(response.data.data, ";");
- // 重构itemList
- let itemList = Array();
- for (let i = 0; i < result.length; i++) {
- let elem = splitString(result[i], ":");
- let output0 = parseInt(elem[0], 10);
- let output1 = parseInt(elem[1], 10);
- itemList.push([output0, output1]);
- }
- param = JSON.stringify({
- type: "UseCDKV2",
- itemList: itemList,
- channel_id: body.channel_id,
- });
- }
- let sendMsg = new Msg();
- sendMsg.connect(serverUrl, Account);
- logger.info("api cdk 发送服务器 param:", {param: param});
- new Promise((resolve) => {
- setTimeout(async () => {
- sendMsg.CG_TEST_PROTO(body.account, param, body.serverId);
- }, 1000);
- });
- } catch (error) {
- console.log(error);
- }
- ctx.body = ApiController.success("success", 0);
- }
- async banUser(ctx) {
- let data = ctx.request.body;
- logger.info("banUser 接口请求 data:", {data: data});
- if (!data.server_tag) {
- ctx.body = ApiController.fail("区服id不能为空", -1, "");
- return;
- }
- let banInfo = {};
- switch (parseInt(data.ban_type)) {
- case 1:
- banInfo = {
- roleBanInfo: {
- channelTag: data.channel_id,
- serverTag: data.server_tag,
- roleTag: data.role_tag,
- banTime: data.ban_time,
- },
- type: "setBan",
- };
- break;
- case 2:
- banInfo = {
- accountBanInfo: {
- channelTag: data.channel_id,
- accountTag: data.account_tag,
- banTime: data.ban_time,
- },
- type: "setBan",
- };
- break;
- case 3:
- banInfo = {
- appBanInfo: {
- appId: data.device_id,
- banTime: data.ban_time,
- },
- type: "setBan",
- };
- break;
- default:
- }
- logger.info("banUser 发送服务器 banInfo:", banInfo);
- let url = await getServerList(data.server_tag, data.channel_id);
- if (!url) {
- ctx.body = ApiController.fail(
- `区服id错误: serverId ${data.server_tag}`,
- 1
- );
- return;
- }
- let param = JSON.stringify(banInfo);
- logger.info("banUser 发送服务器 json字符串: " + param);
- let sendMsg = new Msg();
- sendMsg.connect(url, Account);
- new Promise((resolve) => {
- setTimeout(async () => {
- sendMsg.CG_TEST_PROTO("test", param, data.server_tag);
- // sendMsg.CG_SET_BAN(param);
- }, 1000);
- });
- ctx.body = ApiController.success("success", 0);
- }
- async uicFilter4399(ctx) {
- let body = ctx.request.body;
- let channelConfig = ChannelConfigManager.getConfig(6);
- if (body.is_new == 1) {
- channelConfig = ChannelConfigManager.getConfig(999);
- }
- logger.info("uicFilter4399 body:", {data: body});
- let toCheck = body.toCheck;
- let signStr = channelConfig.loginConfig?.signKey + toCheck;
- logger.info("uicFilter4399 signStr:", {signStr: signStr});
- let apiParams = {
- toCheck: toCheck,
- app: channelConfig.loginConfig.appId,
- byPinyin: true,
- isBatch: false,
- sig: CryptoJS.MD5(signStr).toString(),
- };
- logger.info("uicFilter4399 apiParams:", {data: apiParams});
- const queryStr = Object.entries(apiParams)
- .map(
- ([key, value]) =>
- `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
- )
- .join("&");
- let url = "https://wo.webgame138.com/test/matchService.do" + "?" + queryStr;
- // let url = "https://wo.webgame138.com/test/matchService.do";
- logger.info("uicFilter4399 url:", {url: url});
- try {
- // let response = await axios.get(url, {
- // timeout: 10000, // 设置10秒超时
- // });
- const response = await axios.post(url, apiParams, {
- headers: {
- "Content-Type": "application/json",
- },
- });
- logger.info("uicFilter4399 接口返回 response:", {data: response.data});
- ctx.body = ApiController.success("success", 0, false, response.data);
- } catch (error) {
- console.log(error);
- ctx.body = ApiController.fail(error.message || "请求失败", 1);
- }
- }
- async roleList4399(ctx) {
- let body = ctx.request.body;
- logger.info("RoleList4399 请求参数:", {body: body});
- let data = {
- userId: body.userId,
- server: body.server,
- is_new: ctx.query.is_new || 0
- };
- let port = 8004;
- let host = "127.0.0.1";
- let url = "http://" + host + ":" + port + "/api/roleList/checkBy4399";
- logger.info("RoleList4399 url:", {url: url});
- try {
- const response = await axios.post(url, data, {
- headers: {
- "Content-Type": "application/json",
- },
- });
- logger.info("RoleList4399 返回 response:", {data: response.data});
- ctx.body = response.data;
- } catch (error) {
- console.log(error);
- }
- }
- async cdkBy4399(ctx) {
- let body = ctx.request.body;
- logger.info("cdkBy4399:", {data: body});
- let server = body.server || 1;
- let channel = 5;
- let data = {
- code: body.giftId,
- userId: body.userId,
- channelId: channel,
- };
- if (body.uuid) {
- data.userId = body.uuid;
- }
- let serverUrl = await getServerList(server, channel);
- let err = "";
- if (!serverUrl) {
- ctx.body = ApiController.fail(`区服id错误: serverId ${body.serverId}`, 1);
- return;
- }
- let port = 8004;
- let host = "127.0.0.1";
- let url = "http://" + host + ":" + port + "/api/giftCode/exchange";
- logger.info("cdkBy4399接口请求后台 data:", {data: data, url: url});
- try {
- const response = await axios.post(url, data, {
- headers: {
- "Content-Type": "application/json",
- },
- timeout: 10000,
- });
- logger.info("cdkBy4399接口请求后台 接口返回 response:", {
- data: response.data,
- });
- if (response.data.code != 200) {
- ctx.body = ApiController.fail(response.data.msg, 10004);
- return;
- }
- const result = splitString(response.data.data, ";");
- // 重构itemList
- let itemList = Array();
- for (let i = 0; i < result.length; i++) {
- let elem = splitString(result[i], ":");
- let output0 = parseInt(elem[0], 10);
- let output1 = parseInt(elem[1], 10);
- itemList.push([output0, output1]);
- }
- let param = JSON.stringify({
- type: "UseCDKV2",
- itemList: itemList,
- channel_id: channel,
- });
- let sendMsg = new Msg();
- sendMsg.connect(serverUrl, Account);
- logger.info("cdkBy4399 cdk 发送服务器 param:", {param: param});
- new Promise((resolve) => {
- setTimeout(async () => {
- sendMsg.CG_TEST_PROTO("test", param, server);
- }, 1000);
- });
- } catch (error) {
- console.log(error);
- }
- ctx.body = ApiController.success("success", 10000);
- }
- async roleListYfy(ctx) {
- let gameCode = ctx.query.gameCode;
- let timestamp = ctx.query.timestamp;
- let uid = ctx.query.uid;
- let sign = ctx.query.sign;
- let AppSecret = "H1EqhbpA80jt0Jw6Q3T2";
- logger.info("roleListYfy 请求参数:", {
- uid: uid,
- gameCode: gameCode,
- timestamp: timestamp,
- });
- const signStr = `gameCode-${gameCode}×tamp=${timestamp}&uid=${uid}${AppSecret}`;
- const newSign = CryptoJS.MD5(signStr).toString();
- if (newSign != sign) {
- logger.info("roleListYfy 签名错误:", {
- signStr: signStr,
- sign: sign,
- newSign: newSign,
- });
- ctx.body = ApiController.fail("签名错误!!", -1);
- }
- let port = 8004;
- let host = "127.0.0.1";
- let url = "http://" + host + ":" + port + "/api/roleList/checkByYfy";
- logger.info("roleListYfy url:", {url: url});
- try {
- const response = await axios.post(
- url,
- {
- userId: uid,
- },
- {
- headers: {
- "Content-Type": "application/json",
- },
- }
- );
- logger.info("roleListYfy 返回 response:", {data: response.data});
- ctx.body = response.data;
- } catch (error) {
- console.log(error);
- }
- }
- async getQuickSign(ctx) {
- let data = ctx.request.body;
- logger.info("getQuickSign 请求参数:", {body: data});
- if (!SignatureVerifier.verifyMD5Sign(data, ORDER_SIGN_KEY)) {
- logger.error("签名验证失败");
- ctx.body = ApiController.fail("签名错误!!", -1);
- return;
- }
- let key = "H1EqhbpA80jt0Jw6Q3T2";
- let signStr =
- "uid=" +
- data.uid +
- "&username=" +
- data.username +
- "&serverId=" +
- data.serverId +
- "&serverName=" +
- data.serverName +
- "&userRoleId=" +
- data.userRoleId +
- "&userRoleName=" +
- data.userRoleName +
- "&userRoleLevel=" +
- data.userRoleLevel +
- "&vipLevel=" +
- data.vipLevel +
- "&gameRolePower=" +
- data.gameRolePower +
- "&key=" +
- key;
- logger.info("getQuickSign signStr:", {signStr: signStr});
- data.sign = CryptoJS.MD5(signStr).toString();
- ctx.body = ApiController.success("success", 0, false, data);
- }
- /**
- * mianyou开服同步处理
- * @param ctx Koa上下文
- */
- async mianyouSyncServer(ctx) {
- try {
- const data = ctx.request.body;
- logger.info("mianyou开服同步请求参数:", {data});
- // 验证必要参数
- const {serverId, gameServerId, serverName, startTime, channelId} = data;
-
- if (!serverId || !gameServerId || !serverName || !startTime) {
- logger.warn("mianyou开服同步失败: 缺少必要参数", {data});
- ctx.body = ApiController.fail("缺少必要参数: serverId, gameServerId, serverName, startTime");
- return;
- }
- // 获取渠道配置
- const channelConfig = ChannelConfigManager.getConfig(channelId || 1);
- if (!channelConfig) {
- logger.error("mianyou开服同步失败: 未找到渠道配置", {channelId});
- ctx.body = ApiController.fail("未找到渠道配置");
- return;
- }
- // 创建MianyouChannelHandler实例
- const mianyouHandler = new MianyouChannelHandler();
- // 调用开服同步方法
- const result = await mianyouHandler.openServer(
- parseInt(serverId),
- gameServerId,
- serverName,
- startTime,
- channelConfig
- );
- logger.info("mianyou开服同步结果:", {result});
- // 根据返回结果设置响应
- if (result.status === 0) {
- ctx.body = ApiController.success("开服同步成功", 0, false, result);
- } else {
- ctx.body = ApiController.fail(result.msg || "开服同步失败", result.status);
- }
- } catch (error) {
- logger.error("mianyou开服同步异常:", error);
- ctx.body = ApiController.fail("服务器内部错误", -1);
- }
- }
- }
- module.exports = new ApiController();
|