forked from ppfun/pixelplanet
add punishment for dominating country
This commit is contained in:
parent
ccdf670291
commit
057f60f049
|
@ -11,6 +11,8 @@ import {
|
|||
storeOnlinUserAmount,
|
||||
getCountryDailyHistory,
|
||||
getCountryRanks,
|
||||
getHourlyCountryStats,
|
||||
storeHourlyCountryStats,
|
||||
getTopDailyHistory,
|
||||
storeHourlyPixelsPlaced,
|
||||
getHourlyPixelStats,
|
||||
|
@ -20,30 +22,38 @@ import socketEvents from '../socket/socketEvents';
|
|||
import logger from './logger';
|
||||
|
||||
import { MINUTE } from './constants';
|
||||
import { PUNISH_DOMINATOR } from './config';
|
||||
import { DailyCron, HourlyCron } from '../utils/cron';
|
||||
|
||||
class Ranks {
|
||||
ranks = {
|
||||
// ranking today of users by pixels
|
||||
dailyRanking: [],
|
||||
// ranking of users by pixels
|
||||
ranking: [],
|
||||
// ranking today of countries by pixels
|
||||
dailyCRanking: [],
|
||||
// ranking hourly of countries by pixels
|
||||
cHourlyStats: [],
|
||||
// yesterdays ranking of users by pixels
|
||||
prevTop: [],
|
||||
// online user amount by hour
|
||||
onlineStats: [],
|
||||
// ranking of countries by day
|
||||
cHistStats: [],
|
||||
// ranking of users by day
|
||||
histStats: { users: [], stats: [] },
|
||||
// pixels placed by hour
|
||||
pHourlyStats: [],
|
||||
// pixels placed by day
|
||||
pDailyStats: [],
|
||||
};
|
||||
|
||||
// if a country dominates, adjust its cooldown
|
||||
#punishedCountry;
|
||||
#punishmentFactor;
|
||||
|
||||
constructor() {
|
||||
this.ranks = {
|
||||
// ranking today of users by pixels
|
||||
dailyRanking: [],
|
||||
// ranking of users by pixels
|
||||
ranking: [],
|
||||
// ranking today of countries by pixels
|
||||
dailyCRanking: [],
|
||||
// yesterdays ranking of users by pixels
|
||||
prevTop: [],
|
||||
// online user amount by hour
|
||||
onlineStats: [],
|
||||
// ranking of countries by day
|
||||
cHistStats: [],
|
||||
// ranking of users by day
|
||||
histStats: { users: [], stats: [] },
|
||||
// pixels placed by hour
|
||||
pHourlyStats: [],
|
||||
// pixels placed by day
|
||||
pDailyStats: [],
|
||||
};
|
||||
/*
|
||||
* we go through socketEvents for sharding
|
||||
*/
|
||||
|
@ -70,12 +80,59 @@ class Ranks {
|
|||
if (!newRanks) {
|
||||
return;
|
||||
}
|
||||
if (newRanks.cHourlyStats) {
|
||||
this.setPunishments(newRanks.cHourlyStats);
|
||||
}
|
||||
this.ranks = {
|
||||
...this.ranks,
|
||||
...newRanks,
|
||||
};
|
||||
}
|
||||
|
||||
setPunishments(cHourlyStats) {
|
||||
if (!cHourlyStats.length || !PUNISH_DOMINATOR) {
|
||||
return;
|
||||
}
|
||||
let outnumbered = 0;
|
||||
const { cc: leadingCountry } = cHourlyStats[0];
|
||||
let { px: margin } = cHourlyStats[0];
|
||||
for (let i = 1; i < cHourlyStats.length; i += 1) {
|
||||
margin -= cHourlyStats[i].px;
|
||||
if (margin < 0) {
|
||||
break;
|
||||
}
|
||||
outnumbered += 1;
|
||||
}
|
||||
/*
|
||||
* if the leading country places more pixels
|
||||
* than the fellowing 2+ countries after,
|
||||
* 20% gets added to the cooldown for every following
|
||||
* country, cailed at 200%;
|
||||
*/
|
||||
if (outnumbered > 2) {
|
||||
this.#punishedCountry = leadingCountry;
|
||||
let punishmentFactor = 1 + 0.2 * (outnumbered - 1);
|
||||
if (punishmentFactor > 2) {
|
||||
punishmentFactor = 2;
|
||||
}
|
||||
this.#punishmentFactor = punishmentFactor;
|
||||
logger.info(
|
||||
// eslint-disable-next-line max-len
|
||||
`Punishment for dominating country ${leadingCountry} of ${punishmentFactor}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.#punishedCountry = null;
|
||||
this.#punishmentFactor = 1.0;
|
||||
}
|
||||
|
||||
getCountryCoolDownFactor(country) {
|
||||
if (this.#punishedCountry === country) {
|
||||
return this.#punishmentFactor;
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
static async updateRanking() {
|
||||
// only main shard does it
|
||||
if (!socketEvents.amIImportant()) {
|
||||
|
@ -107,10 +164,12 @@ class Ranks {
|
|||
const onlineStats = await getOnlineUserStats();
|
||||
const cHistStats = await getCountryDailyHistory();
|
||||
const pHourlyStats = await getHourlyPixelStats();
|
||||
const cHourlyStats = await getHourlyCountryStats(1, 100);
|
||||
const ret = {
|
||||
onlineStats,
|
||||
cHistStats,
|
||||
pHourlyStats,
|
||||
cHourlyStats,
|
||||
};
|
||||
if (socketEvents.amIImportant()) {
|
||||
// only main shard sends to others
|
||||
|
@ -148,6 +207,7 @@ class Ranks {
|
|||
const amount = socketEvents.onlineCounter.total;
|
||||
await storeOnlinUserAmount(amount);
|
||||
await storeHourlyPixelsPlaced();
|
||||
await storeHourlyCountryStats(1, 100);
|
||||
await Ranks.hourlyUpdateRanking();
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,9 @@ export const BACKUP_DIR = process.env.BACKUP_DIR || null;
|
|||
|
||||
export const OUTGOING_ADDRESS = process.env.OUTGOING_ADDRESS || null;
|
||||
|
||||
// Punish when a country dominates
|
||||
export const PUNISH_DOMINATOR = !!process.env.PUNISH_DOMINATOR;
|
||||
|
||||
// Proxycheck
|
||||
export const USE_PROXYCHECK = parseInt(process.env.USE_PROXYCHECK, 10) || false;
|
||||
export const { PROXYCHECK_KEY } = process.env;
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
import logger, { pixelLogger } from './logger';
|
||||
import allowPlace from '../data/redis/cooldown';
|
||||
import socketEvents from '../socket/socketEvents';
|
||||
import rankings from './Ranks';
|
||||
import { setPixelByOffset } from './setPixel';
|
||||
import isIPAllowed from './isAllowed';
|
||||
import canvases from './canvases';
|
||||
|
@ -127,6 +128,8 @@ export default async function drawByOffsets(
|
|||
}
|
||||
*/
|
||||
|
||||
factor *= rankings.getCountryCoolDownFactor(user.country);
|
||||
|
||||
factor *= 0.75;
|
||||
|
||||
const bcd = canvas.bcd * factor;
|
||||
|
|
|
@ -7,6 +7,9 @@ import { getDateKeyOfTs } from '../../core/utils';
|
|||
export const RANKED_KEY = 'rank';
|
||||
export const DAILY_RANKED_KEY = 'rankd';
|
||||
export const DAILY_CRANKED_KEY = 'crankd';
|
||||
export const HOURLY_CRANKED_KEY = 'crankh';
|
||||
export const PREV_DAILY_CRANKED_KEY = 'pcrankd';
|
||||
export const PREV_DAILY_CRANKED_TS_KEY = 'pcrankdts';
|
||||
export const PREV_DAY_TOP_KEY = 'prankd';
|
||||
const DAY_STATS_RANKS_KEY = 'ds';
|
||||
const CDAY_STATS_RANKS_KEY = 'cds';
|
||||
|
@ -100,6 +103,61 @@ export async function getCountryRanks(start, amount) {
|
|||
return ranks;
|
||||
}
|
||||
|
||||
/*
|
||||
* get previous daily country ranking (one hour before cranks)
|
||||
*/
|
||||
export async function getHourlyCountryStats(start, amount) {
|
||||
start -= 1;
|
||||
amount -= 1;
|
||||
let ranks = await client.zRangeWithScores(
|
||||
HOURLY_CRANKED_KEY, start, start + amount, {
|
||||
REV: true,
|
||||
});
|
||||
ranks = ranks.map((r) => ({
|
||||
cc: r.value,
|
||||
px: Number(r.score),
|
||||
}));
|
||||
return ranks;
|
||||
}
|
||||
|
||||
export async function storeHourlyCountryStats(start, amount) {
|
||||
start -= 1;
|
||||
amount -= 1;
|
||||
const tsNow = Date.now();
|
||||
const prevTs = Number(await client.get(PREV_DAILY_CRANKED_TS_KEY));
|
||||
const prevData = await client.zRangeWithScores(
|
||||
PREV_DAILY_CRANKED_KEY, start, start + amount, {
|
||||
REV: true,
|
||||
});
|
||||
|
||||
await client.copy(DAILY_CRANKED_KEY, PREV_DAILY_CRANKED_KEY, {
|
||||
REAPLACE: true,
|
||||
});
|
||||
await client.set(PREV_DAILY_CRANKED_TS_KEY, String(tsNow));
|
||||
await client.del(HOURLY_CRANKED_KEY);
|
||||
|
||||
if (prevTs && prevTs > tsNow - 1000 * 3600 * 1.5) {
|
||||
const curData = await client.zRangeWithScores(
|
||||
DAILY_CRANKED_KEY, start, start + amount, {
|
||||
REV: true,
|
||||
});
|
||||
const prevRanks = new Map();
|
||||
prevData.forEach(({ value, score }) => prevRanks.set(value, score));
|
||||
const addArr = [];
|
||||
curData.forEach(({ value: cc, score: curPx }) => {
|
||||
const prevPx = prevData.get(cc) || 0;
|
||||
const px = (curPx > prevPx) ? curPx - prevPx : curPx;
|
||||
addArr.push({
|
||||
score: cc,
|
||||
value: px,
|
||||
});
|
||||
});
|
||||
if (addArr.length) {
|
||||
await client.zAdd(HOURLY_CRANKED_KEY, addArr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get top 10 from previous day
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue
Block a user