Merge branch 'second' of http://git.kingsome.cn/node/card_svr into second
This commit is contained in:
commit
996274b288
@ -1,8 +1,8 @@
|
|||||||
import axios from "axios";
|
import axios from 'axios'
|
||||||
import {Config} from "../cfg/Config";
|
import { Config } from '../cfg/Config'
|
||||||
import {debugRoom, error} from "./Debug";
|
import { debugRoom, error } from './Debug'
|
||||||
|
|
||||||
let config: Config = require('../../config/config.json');
|
let config: Config = require('../../config/config.json')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取卡组详情
|
* 获取卡组详情
|
||||||
@ -12,15 +12,15 @@ let config: Config = require('../../config/config.json');
|
|||||||
* @return {Promise<AxiosResponse<any>>}
|
* @return {Promise<AxiosResponse<any>>}
|
||||||
*/
|
*/
|
||||||
export function getCardGroup(accountid: string, heroid: number, cardgroup: string) {
|
export function getCardGroup(accountid: string, heroid: number, cardgroup: string) {
|
||||||
return axios.get(`${config.info_svr}/${accountid}/group_info/${heroid}/${cardgroup}`, )
|
return axios.get(`${ config.info_svr }/${ accountid }/group_info/${ heroid }/${ cardgroup }`)
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
let res = response.data;
|
let res = response.data
|
||||||
if (res.errcode) {
|
if (res.errcode) {
|
||||||
throw new Error(res.errmsg);
|
throw new Error(res.errmsg)
|
||||||
} else {
|
} else {
|
||||||
return res.data;
|
return res.data
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,8 +30,8 @@ export function getCardGroup(accountid: string, heroid: number, cardgroup: strin
|
|||||||
* @return {Promise<AxiosResponse<any>>}
|
* @return {Promise<AxiosResponse<any>>}
|
||||||
*/
|
*/
|
||||||
export function requestUnlockHero(accountid: string, heroid: number | string) {
|
export function requestUnlockHero(accountid: string, heroid: number | string) {
|
||||||
let data = {"type": 0};
|
let data = { 'type': 0 }
|
||||||
return axios.post(`${config.info_svr}/${accountid}/hero/unlock/${heroid}`, data);
|
return axios.post(`${ config.info_svr }/${ accountid }/hero/unlock/${ heroid }`, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,19 +39,70 @@ export function requestUnlockHero(accountid: string, heroid: number | string) {
|
|||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
export async function reportGameResult(data: any) {
|
export async function reportGameResult(data: any) {
|
||||||
let dataStr = JSON.stringify(data);
|
let dataStr = JSON.stringify(data)
|
||||||
|
|
||||||
let reqConfig = {
|
let reqConfig = {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
url: `${config.info_svr}/record/save`,
|
url: `${ config.info_svr }/record/save`,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
data : dataStr
|
data: dataStr
|
||||||
};
|
}
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return axios(reqConfig)
|
return axios(reqConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用物品
|
||||||
|
* @param {string} accountid
|
||||||
|
* @param {number} itemid
|
||||||
|
* @param {number} count
|
||||||
|
*/
|
||||||
|
export async function useItem(accountid: string, itemid: number, count: number) {
|
||||||
|
const data = { itemid, count }
|
||||||
|
let dataStr = JSON.stringify(data)
|
||||||
|
let reqConfig = {
|
||||||
|
method: 'post',
|
||||||
|
url: `${ config.info_svr }/${ accountid }/useitem`,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: dataStr
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
return axios(reqConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查匹配所需的资源是否足够
|
||||||
|
* @param {string} accountid
|
||||||
|
* @param {string} matchid
|
||||||
|
* @return {Promise<any>}
|
||||||
|
*/
|
||||||
|
export async function checkMatchTicket(accountid: string, matchid: string) {
|
||||||
|
const data = { matchid }
|
||||||
|
const url = `${ config.info_svr }/${ accountid }/beginmatch`
|
||||||
|
let reqConfig = {
|
||||||
|
method: 'post',
|
||||||
|
url,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: JSON.stringify(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
return axios(reqConfig).then(function (response) {
|
||||||
|
let res = response.data
|
||||||
|
if (res.errcode) {
|
||||||
|
throw new Error(res.errmsg)
|
||||||
|
} else {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,13 +110,13 @@ export async function reportGameResult(data: any) {
|
|||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
export function createRobot(data: any) {
|
export function createRobot(data: any) {
|
||||||
axios.get('http://127.0.0.1:2500/robot/create', {
|
axios.get('http://127.0.0.1:2500/robot/create', {
|
||||||
params: data
|
params: data
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
debugRoom(`caeate robot result: `,res.data);
|
debugRoom(`caeate robot result: `, res.data)
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
error(err);
|
error(err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
2
src/global.d.ts
vendored
2
src/global.d.ts
vendored
@ -31,7 +31,7 @@ declare module "colyseus" {
|
|||||||
dispatcher: Dispatcher;
|
dispatcher: Dispatcher;
|
||||||
mainClock: Delayed;
|
mainClock: Delayed;
|
||||||
robotCount: number;
|
robotCount: number;
|
||||||
match: boolean;
|
match: string | undefined ;
|
||||||
score: number;
|
score: number;
|
||||||
/**
|
/**
|
||||||
* 根据sessionId获取client
|
* 根据sessionId获取client
|
||||||
|
@ -31,7 +31,7 @@ export class GeneralRoom extends Room {
|
|||||||
gameClock: Map<string, Delayed> = new Map();
|
gameClock: Map<string, Delayed> = new Map();
|
||||||
|
|
||||||
assistMap: Map<String, RobotClient> = new Map();
|
assistMap: Map<String, RobotClient> = new Map();
|
||||||
match = false;
|
match = '';
|
||||||
robotCount = 0;
|
robotCount = 0;
|
||||||
|
|
||||||
async onAuth (client:Client, options: any, request: IncomingMessage) {
|
async onAuth (client:Client, options: any, request: IncomingMessage) {
|
||||||
@ -48,7 +48,7 @@ export class GeneralRoom extends Room {
|
|||||||
if (options.count) {
|
if (options.count) {
|
||||||
this.robotCount = Math.min(Math.max(0, options.count), this.maxClients - 1);
|
this.robotCount = Math.min(Math.max(0, options.count), this.maxClients - 1);
|
||||||
}
|
}
|
||||||
this.match = !!options.match || false;
|
this.match = options.match;
|
||||||
if (options.score) {
|
if (options.score) {
|
||||||
this.score = options.score;
|
this.score = options.score;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import {Client, generateId, matchMaker, Room} from "colyseus";
|
import { Client, generateId, matchMaker, Room, ServerError } from 'colyseus'
|
||||||
import {BaseConst} from "../constants/BaseConst";
|
import { BaseConst } from '../constants/BaseConst'
|
||||||
|
import { IncomingMessage } from 'http'
|
||||||
|
import { checkMatchTicket } from '../common/WebApi'
|
||||||
|
|
||||||
interface MatchmakingGroup {
|
interface MatchmakingGroup {
|
||||||
averageRank: number;
|
averageRank: number;
|
||||||
@ -13,7 +15,7 @@ interface MatchmakingGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ClientStat {
|
interface ClientStat {
|
||||||
clients: Map<string, {client: Client, options: any, seat?: number}>;
|
clients: Map<string, { client: Client, options: any, seat?: number }>;
|
||||||
waitingTime: number;
|
waitingTime: number;
|
||||||
options?: any;
|
options?: any;
|
||||||
groupTag?: string;
|
groupTag?: string;
|
||||||
@ -30,42 +32,42 @@ export class RankedLobbyRoom extends Room {
|
|||||||
* reached) will be matched together. Your room should fill the remaining
|
* reached) will be matched together. Your room should fill the remaining
|
||||||
* spots with "bots" on this case.
|
* spots with "bots" on this case.
|
||||||
*/
|
*/
|
||||||
allowUnmatchedGroups: boolean = true;
|
allowUnmatchedGroups: boolean = true
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluate groups for each client at interval
|
* Evaluate groups for each client at interval
|
||||||
*/
|
*/
|
||||||
evaluateGroupsInterval = 1000;
|
evaluateGroupsInterval = 1000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Groups of players per iteration
|
* Groups of players per iteration
|
||||||
*/
|
*/
|
||||||
groups: MatchmakingGroup[] = [];
|
groups: MatchmakingGroup[] = []
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* name of the room to create
|
* name of the room to create
|
||||||
*/
|
*/
|
||||||
roomToCreate = "general_room";
|
roomToCreate = 'general_room'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最大匹配时间
|
* 最大匹配时间
|
||||||
*/
|
*/
|
||||||
maxWaitingTime = 15 * 1000;
|
maxWaitingTime = 15 * 1000
|
||||||
/**
|
/**
|
||||||
* 超过该时间, 组队玩家可匹配单排玩家
|
* 超过该时间, 组队玩家可匹配单排玩家
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
groupAddOneTime = 10 * 1000;
|
groupAddOneTime = 10 * 1000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* after this time, try to fit this client with a not-so-compatible group
|
* after this time, try to fit this client with a not-so-compatible group
|
||||||
*/
|
*/
|
||||||
maxWaitingTimeForPriority?: number = 10 * 1000;
|
maxWaitingTimeForPriority?: number = 10 * 1000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* number of players on each match
|
* number of players on each match
|
||||||
*/
|
*/
|
||||||
numClientsToMatch = 4;
|
numClientsToMatch = 4
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * after a group is ready, clients have this amount of milliseconds to confirm
|
// * after a group is ready, clients have this amount of milliseconds to confirm
|
||||||
@ -75,45 +77,59 @@ export class RankedLobbyRoom extends Room {
|
|||||||
/**
|
/**
|
||||||
* rank and group cache per-player
|
* rank and group cache per-player
|
||||||
*/
|
*/
|
||||||
stats: ClientStat[] = [];
|
stats: ClientStat[] = []
|
||||||
rank_mpa = 0.2;
|
rank_mpa = 0.2
|
||||||
fair_ir = 1.2;
|
fair_ir = 1.2
|
||||||
step_ir = 1.3;
|
step_ir = 1.3
|
||||||
|
matchid = '100001'
|
||||||
|
|
||||||
|
async onAuth(client: Client, options: any, request: IncomingMessage) {
|
||||||
|
let { accountid } = options
|
||||||
|
if (!accountid) {
|
||||||
|
throw new ServerError(10, 'not enough params')
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await checkMatchTicket(accountid, this.matchid)
|
||||||
|
} catch (err) {
|
||||||
|
throw new ServerError(11, 'not enough ticket')
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
onCreate(options: any) {
|
onCreate(options: any) {
|
||||||
const fc = global.$cfg.get(BaseConst.FORMULA);
|
const fc = global.$cfg.get(BaseConst.FORMULA)
|
||||||
this.rank_mpa = fc.get(70028).number / 100;
|
this.rank_mpa = fc.get(70028).number / 100
|
||||||
this.fair_ir = fc.get(70029).number / 100 + 1;
|
this.fair_ir = fc.get(70029).number / 100 + 1
|
||||||
this.step_ir = fc.get(70031).number / 100 + 1;
|
this.step_ir = fc.get(70031).number / 100 + 1
|
||||||
this.groupAddOneTime = fc.get(70023).number * 1000;
|
this.groupAddOneTime = fc.get(70023).number * 1000
|
||||||
this.maxWaitingTime = (fc.get(70024).number + fc.get(70025).number) * 1000;
|
this.maxWaitingTime = (fc.get(70024).number + fc.get(70025).number) * 1000
|
||||||
if (options.maxWaitingTime) {
|
if (options.maxWaitingTime) {
|
||||||
this.maxWaitingTime = options.maxWaitingTime;
|
this.maxWaitingTime = options.maxWaitingTime
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.numClientsToMatch) {
|
if (options.numClientsToMatch) {
|
||||||
this.numClientsToMatch = options.numClientsToMatch;
|
this.numClientsToMatch = options.numClientsToMatch
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onMessage("bye", (client: Client, message: any) => {
|
this.onMessage('bye', (client: Client, message: any) => {
|
||||||
const stat = this.stats.find(obj => obj.clients.has(client.sessionId));
|
const stat = this.stats.find(obj => obj.clients.has(client.sessionId))
|
||||||
|
|
||||||
if (stat && stat.group && typeof (stat.group.confirmed) === "number") {
|
if (stat && stat.group && typeof (stat.group.confirmed) === 'number') {
|
||||||
stat.confirmed = true;
|
stat.confirmed = true
|
||||||
stat.group.confirmed++;
|
stat.group.confirmed++
|
||||||
//stat.clients.delete(client.sessionId);
|
//stat.clients.delete(client.sessionId);
|
||||||
client.leave();
|
client.leave()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.onMessage('gogogo', (client: Client, message: any) => {
|
this.onMessage('gogogo', (client: Client, message: any) => {
|
||||||
const stat = this.stats.find(obj => obj.clients.has(client.sessionId));
|
const stat = this.stats.find(obj => obj.clients.has(client.sessionId))
|
||||||
stat.priority = true;
|
stat.priority = true
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redistribute clients into groups at every interval
|
* Redistribute clients into groups at every interval
|
||||||
*/
|
*/
|
||||||
this.setSimulationInterval(() => this.redistributeGroups(), this.evaluateGroupsInterval);
|
this.setSimulationInterval(() => this.redistributeGroups(), this.evaluateGroupsInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
onJoin(client: Client, options: any) {
|
onJoin(client: Client, options: any) {
|
||||||
@ -124,17 +140,17 @@ export class RankedLobbyRoom extends Room {
|
|||||||
* 如果找到的记录, clients是1, 则把当前client添加到该记录中, 同时更新rank
|
* 如果找到的记录, clients是1, 则把当前client添加到该记录中, 同时更新rank
|
||||||
*/
|
*/
|
||||||
if (options.group) {
|
if (options.group) {
|
||||||
let length = this.stats.length;
|
let length = this.stats.length
|
||||||
let groupData;
|
let groupData
|
||||||
for (let i = 0; i < length; i++) {
|
for (let i = 0; i < length; i++) {
|
||||||
if (this.stats[i].groupTag == options.group) {
|
if (this.stats[i].groupTag == options.group) {
|
||||||
groupData = this.stats[i];
|
groupData = this.stats[i]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!groupData) {
|
if (!groupData) {
|
||||||
let clientMap = new Map();
|
let clientMap = new Map()
|
||||||
clientMap.set(client.sessionId, {client, options});
|
clientMap.set(client.sessionId, { client, options })
|
||||||
groupData = {
|
groupData = {
|
||||||
clients: clientMap,
|
clients: clientMap,
|
||||||
rank: options.rank,
|
rank: options.rank,
|
||||||
@ -142,112 +158,112 @@ export class RankedLobbyRoom extends Room {
|
|||||||
waitingTime: 0,
|
waitingTime: 0,
|
||||||
options
|
options
|
||||||
}
|
}
|
||||||
this.stats.push(groupData);
|
this.stats.push(groupData)
|
||||||
} else {
|
} else {
|
||||||
if (groupData.clients.size >= 2) {
|
if (groupData.clients.size >= 2) {
|
||||||
let clientMap = new Map();
|
let clientMap = new Map()
|
||||||
options.group = generateId();
|
options.group = generateId()
|
||||||
clientMap.set(client.sessionId, {client, options});
|
clientMap.set(client.sessionId, { client, options })
|
||||||
this.stats.push({
|
this.stats.push({
|
||||||
clients: clientMap,
|
clients: clientMap,
|
||||||
rank: options.rank,
|
rank: options.rank,
|
||||||
waitingTime: 0,
|
waitingTime: 0,
|
||||||
options
|
options
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
groupData.clients.set(client.sessionId, {client, options});
|
groupData.clients.set(client.sessionId, { client, options })
|
||||||
groupData.rank = (groupData.rank + options.rank) / 2 * (1 + this.rank_mpa);
|
groupData.rank = (groupData.rank + options.rank) / 2 * (1 + this.rank_mpa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
client.send("clients", groupData.clients.size);
|
client.send('clients', groupData.clients.size)
|
||||||
} else {
|
} else {
|
||||||
let clientMap = new Map();
|
let clientMap = new Map()
|
||||||
clientMap.set(client.sessionId, {client, options});
|
clientMap.set(client.sessionId, { client, options })
|
||||||
this.stats.push({
|
this.stats.push({
|
||||||
clients: clientMap,
|
clients: clientMap,
|
||||||
rank: options.rank,
|
rank: options.rank,
|
||||||
waitingTime: 0,
|
waitingTime: 0,
|
||||||
options
|
options
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
client.send("clients", 1);
|
client.send('clients', 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
createGroup() {
|
createGroup() {
|
||||||
let group: MatchmakingGroup = {clients: [], averageRank: 0, count: 0};
|
let group: MatchmakingGroup = { clients: [], averageRank: 0, count: 0 }
|
||||||
this.groups.push(group);
|
this.groups.push(group)
|
||||||
return group;
|
return group
|
||||||
}
|
}
|
||||||
|
|
||||||
redistributeGroups() {
|
redistributeGroups() {
|
||||||
// re-set all groups
|
// re-set all groups
|
||||||
this.groups = [];
|
this.groups = []
|
||||||
|
|
||||||
const stats = this.stats.sort((a, b) => a.rank - b.rank);
|
const stats = this.stats.sort((a, b) => a.rank - b.rank)
|
||||||
|
|
||||||
let currentGroup: MatchmakingGroup = this.createGroup();
|
let currentGroup: MatchmakingGroup = this.createGroup()
|
||||||
let totalRank = 0;
|
let totalRank = 0
|
||||||
// 先过滤一边组队的情况
|
// 先过滤一边组队的情况
|
||||||
for (let i = 0, l = stats.length; i < l; i++) {
|
for (let i = 0, l = stats.length; i < l; i++) {
|
||||||
if (stats[i].clients.size == 1) {
|
if (stats[i].clients.size == 1) {
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
const stat = stats[i];
|
const stat = stats[i]
|
||||||
stat.waitingTime += this.clock.deltaTime;
|
stat.waitingTime += this.clock.deltaTime
|
||||||
if (stat.group && stat.group.ready) {
|
if (stat.group && stat.group.ready) {
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
if (currentGroup.averageRank > 0) {
|
if (currentGroup.averageRank > 0) {
|
||||||
const diff = Math.abs(stat.rank - currentGroup.averageRank);
|
const diff = Math.abs(stat.rank - currentGroup.averageRank)
|
||||||
const diffRatio = (diff / currentGroup.averageRank);
|
const diffRatio = (diff / currentGroup.averageRank)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* figure out how to identify the diff ratio that makes sense
|
* figure out how to identify the diff ratio that makes sense
|
||||||
*/
|
*/
|
||||||
if (diffRatio > this.step_ir) {
|
if (diffRatio > this.step_ir) {
|
||||||
currentGroup = this.createGroup();
|
currentGroup = this.createGroup()
|
||||||
totalRank = 0;
|
totalRank = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stat.group = currentGroup;
|
stat.group = currentGroup
|
||||||
currentGroup.clients.push(stat);
|
currentGroup.clients.push(stat)
|
||||||
currentGroup.count += stat.clients.size;
|
currentGroup.count += stat.clients.size
|
||||||
|
|
||||||
totalRank += stat.rank;
|
totalRank += stat.rank
|
||||||
currentGroup.averageRank = totalRank / currentGroup.clients.length;
|
currentGroup.averageRank = totalRank / currentGroup.clients.length
|
||||||
if (currentGroup.count === this.numClientsToMatch) {
|
if (currentGroup.count === this.numClientsToMatch) {
|
||||||
currentGroup.ready = true;
|
currentGroup.ready = true
|
||||||
currentGroup = this.createGroup();
|
currentGroup = this.createGroup()
|
||||||
totalRank = 0;
|
totalRank = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
totalRank = 0;
|
totalRank = 0
|
||||||
currentGroup = this.createGroup();
|
currentGroup = this.createGroup()
|
||||||
for (let i = 0, l = stats.length; i < l; i++) {
|
for (let i = 0, l = stats.length; i < l; i++) {
|
||||||
|
|
||||||
const stat = stats[i];
|
const stat = stats[i]
|
||||||
|
|
||||||
if (stats[i].clients.size == 1) {
|
if (stats[i].clients.size == 1) {
|
||||||
stat.waitingTime += this.clock.deltaTime;
|
stat.waitingTime += this.clock.deltaTime
|
||||||
} else {
|
} else {
|
||||||
if (stat.waitingTime < this.groupAddOneTime) {
|
if (stat.waitingTime < this.groupAddOneTime) {
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* do not attempt to re-assign groups for clients inside "ready" groups
|
* do not attempt to re-assign groups for clients inside "ready" groups
|
||||||
*/
|
*/
|
||||||
if (stat.group && stat.group.ready) {
|
if (stat.group && stat.group.ready) {
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
if (currentGroup.count + stat.clients.size > this.maxClients) {
|
if (currentGroup.count + stat.clients.size > this.maxClients) {
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
if (stat.priority) {
|
if (stat.priority) {
|
||||||
currentGroup.priority = true;
|
currentGroup.priority = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -263,24 +279,24 @@ export class RankedLobbyRoom extends Room {
|
|||||||
currentGroup.averageRank > 0 &&
|
currentGroup.averageRank > 0 &&
|
||||||
!currentGroup.priority
|
!currentGroup.priority
|
||||||
) {
|
) {
|
||||||
const diff = Math.abs(stat.rank - currentGroup.averageRank);
|
const diff = Math.abs(stat.rank - currentGroup.averageRank)
|
||||||
const diffRatio = (diff / currentGroup.averageRank);
|
const diffRatio = (diff / currentGroup.averageRank)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* figure out how to identify the diff ratio that makes sense
|
* figure out how to identify the diff ratio that makes sense
|
||||||
*/
|
*/
|
||||||
if (diffRatio > this.fair_ir) {
|
if (diffRatio > this.fair_ir) {
|
||||||
currentGroup = this.createGroup();
|
currentGroup = this.createGroup()
|
||||||
totalRank = 0;
|
totalRank = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stat.group = currentGroup;
|
stat.group = currentGroup
|
||||||
currentGroup.clients.push(stat);
|
currentGroup.clients.push(stat)
|
||||||
currentGroup.count += stat.clients.size;
|
currentGroup.count += stat.clients.size
|
||||||
|
|
||||||
totalRank += stat.rank;
|
totalRank += stat.rank
|
||||||
currentGroup.averageRank = totalRank / currentGroup.count;
|
currentGroup.averageRank = totalRank / currentGroup.count
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(currentGroup.count === this.numClientsToMatch) ||
|
(currentGroup.count === this.numClientsToMatch) ||
|
||||||
@ -292,80 +308,81 @@ export class RankedLobbyRoom extends Room {
|
|||||||
(stat.waitingTime >= this.maxWaitingTime && this.allowUnmatchedGroups) ||
|
(stat.waitingTime >= this.maxWaitingTime && this.allowUnmatchedGroups) ||
|
||||||
stat.priority
|
stat.priority
|
||||||
) {
|
) {
|
||||||
currentGroup.ready = true;
|
currentGroup.ready = true
|
||||||
currentGroup = this.createGroup();
|
currentGroup = this.createGroup()
|
||||||
totalRank = 0;
|
totalRank = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.checkGroupsReady();
|
this.checkGroupsReady()
|
||||||
}
|
}
|
||||||
|
|
||||||
generateSeat(index: number): number {
|
generateSeat(index: number): number {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0:
|
case 0:
|
||||||
return 0;
|
return 0
|
||||||
case 1:
|
case 1:
|
||||||
return 3;
|
return 3
|
||||||
case 2:
|
case 2:
|
||||||
return 1;
|
return 1
|
||||||
case 3:
|
case 3:
|
||||||
return 2;
|
return 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkGroupsReady() {
|
async checkGroupsReady() {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
this.groups
|
this.groups
|
||||||
.map(async (group) => {
|
.map(async (group) => {
|
||||||
if (group.ready) {
|
if (group.ready) {
|
||||||
group.confirmed = 0;
|
group.confirmed = 0
|
||||||
let score = 0;
|
let score = 0
|
||||||
let count = 0;
|
let count = 0
|
||||||
group.clients.map(client => {
|
group.clients.map(client => {
|
||||||
for (let [,data] of client.clients) {
|
for (let [, data] of client.clients) {
|
||||||
score += (data.options?.score || 0);
|
score += (data.options?.score || 0)
|
||||||
count ++;
|
count++
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
let avaScore = score / count;
|
let avaScore = score / count
|
||||||
/**
|
/**
|
||||||
* Create room instance in the server.
|
* Create room instance in the server.
|
||||||
*/
|
*/
|
||||||
const room = await matchMaker.createRoom(this.roomToCreate, {
|
const room = await matchMaker.createRoom(this.roomToCreate, {
|
||||||
match: true,
|
match: this.matchid,
|
||||||
rank: group.averageRank,
|
rank: group.averageRank,
|
||||||
score: avaScore,
|
score: avaScore,
|
||||||
count: this.numClientsToMatch - group.count
|
count: this.numClientsToMatch - group.count
|
||||||
});
|
})
|
||||||
// 预处理数据, 确定座次
|
// 预处理数据, 确定座次
|
||||||
let hasGroup = false;
|
let hasGroup = false
|
||||||
for (let client of group.clients) {
|
for (let client of group.clients) {
|
||||||
if (client.clients.size > 1) {
|
if (client.clients.size > 1) {
|
||||||
hasGroup = true;
|
hasGroup = true
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let seat = 0;
|
let seat = 0
|
||||||
if (hasGroup) {
|
if (hasGroup) {
|
||||||
for (let client of group.clients) {
|
for (let client of group.clients) {
|
||||||
if (client.clients.size > 1) {
|
if (client.clients.size > 1) {
|
||||||
for (let [,sub] of client.clients) {
|
for (let [, sub] of client.clients) {
|
||||||
sub.seat = this.generateSeat(seat ++);
|
sub.seat = this.generateSeat(seat++)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let client of group.clients) {
|
for (let client of group.clients) {
|
||||||
if (client.clients.size == 1) {
|
if (client.clients.size == 1) {
|
||||||
for (let [,sub] of client.clients) {
|
for (let [, sub] of client.clients) {
|
||||||
sub.seat = this.generateSeat(seat ++);
|
sub.seat = this.generateSeat(seat++)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
group.clients.sort((a, b) => a.rank - b.rank);
|
group.clients.sort((a, b) => a.rank - b.rank)
|
||||||
for (let client of group.clients) {
|
for (let client of group.clients) {
|
||||||
for (let [,sub] of client.clients) {
|
for (let [, sub] of client.clients) {
|
||||||
sub.seat = seat ++;
|
sub.seat = seat++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -376,17 +393,17 @@ export class RankedLobbyRoom extends Room {
|
|||||||
/**
|
/**
|
||||||
* Send room data for new WebSocket connection!
|
* Send room data for new WebSocket connection!
|
||||||
*/
|
*/
|
||||||
for (let [,data] of client.clients) {
|
for (let [, data] of client.clients) {
|
||||||
let matchOpt = {
|
let matchOpt = {
|
||||||
seat: data.seat
|
seat: data.seat
|
||||||
}
|
}
|
||||||
Object.assign(matchOpt, data.options);
|
Object.assign(matchOpt, data.options)
|
||||||
const matchData = await matchMaker.reserveSeatFor(room, matchOpt);
|
const matchData = await matchMaker.reserveSeatFor(room, matchOpt)
|
||||||
let options: any = {seat: data.seat, rank: data.options.rank};
|
let options: any = { seat: data.seat, rank: data.options.rank }
|
||||||
Object.assign(options, matchData);
|
Object.assign(options, matchData)
|
||||||
data.client.send("match_success", options);
|
data.client.send('match_success', options)
|
||||||
}
|
}
|
||||||
}));
|
}))
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Cancel & re-enqueue clients if some of them couldn't confirm connection.
|
// * Cancel & re-enqueue clients if some of them couldn't confirm connection.
|
||||||
@ -404,23 +421,23 @@ export class RankedLobbyRoom extends Room {
|
|||||||
* Notify all clients within the group on how many players are in the queue
|
* Notify all clients within the group on how many players are in the queue
|
||||||
*/
|
*/
|
||||||
group.clients.forEach(client => {
|
group.clients.forEach(client => {
|
||||||
for (let [,data] of client.clients) {
|
for (let [, data] of client.clients) {
|
||||||
data.client.send("clients", group.count);
|
data.client.send('clients', group.count)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
onLeave(client: Client, consented: boolean) {
|
onLeave(client: Client, consented: boolean) {
|
||||||
const stat = this.stats.find(obj => obj.clients.has(client.sessionId));
|
const stat = this.stats.find(obj => obj.clients.has(client.sessionId))
|
||||||
if (stat.clients.size > 1) {
|
if (stat.clients.size > 1) {
|
||||||
stat.clients.delete(client.sessionId);
|
stat.clients.delete(client.sessionId)
|
||||||
let data = [...stat.clients.values()][0];
|
let data = [...stat.clients.values()][0]
|
||||||
stat.rank = data.options.rank;
|
stat.rank = data.options.rank
|
||||||
} else {
|
} else {
|
||||||
this.stats.remove(stat);
|
this.stats.remove(stat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,13 +193,14 @@ export class GameResultCommand extends Command<CardGameState, {}> {
|
|||||||
}
|
}
|
||||||
let time = new GameEnv().gameResultTime * 1000;
|
let time = new GameEnv().gameResultTime * 1000;
|
||||||
this.room.beginSchedule(time, resultTimeOver, 'restart_schedule');
|
this.room.beginSchedule(time, resultTimeOver, 'restart_schedule');
|
||||||
let seasonData = (await self.reportGameResult(winner, mvp.id, results.get(mvp).mvpScore, results)).data.data;
|
let saveData = (await self.reportGameResult(winner, mvp.id, results.get(mvp).mvpScore, results)).data.data;
|
||||||
let resultData: any = {
|
let resultData: any = {
|
||||||
winner: winner,
|
winner: winner,
|
||||||
mvp: mvp.id,
|
mvp: mvp.id,
|
||||||
results: [...results.values()],
|
results: [...results.values()],
|
||||||
statics: statics,
|
statics: statics,
|
||||||
seasonData
|
seasonData: saveData.seasonData,
|
||||||
|
items: saveData.itemData
|
||||||
};
|
};
|
||||||
this.room.bGameResult(resultData);
|
this.room.bGameResult(resultData);
|
||||||
this.resetAllState();
|
this.resetAllState();
|
||||||
@ -253,7 +254,8 @@ export class GameResultCommand extends Command<CardGameState, {}> {
|
|||||||
roomid: this.room.roomId,
|
roomid: this.room.roomId,
|
||||||
round: this.state.round,
|
round: this.state.round,
|
||||||
winner: winner,
|
winner: winner,
|
||||||
season: this.room.match ? 1: 0
|
season: this.room.match ? 1: 0,
|
||||||
|
matchid: this.room.match
|
||||||
}
|
}
|
||||||
let players: any[] = [];
|
let players: any[] = [];
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user